diff --git a/DxfColors.h b/DxfColors.h index 28ccaae..835cd9c 100644 --- a/DxfColors.h +++ b/DxfColors.h @@ -7,7 +7,7 @@ // // // Modifiche : 17.04.14 DS Creazione modulo. -// +// 08.08.14 DS Corretti tutti i valori. // //---------------------------------------------------------------------------- @@ -26,249 +26,249 @@ const unsigned char DxfColors[][3] = { {255, 255, 255}, {128, 128, 128}, {192, 192, 192}, - {255, 0, 0}, + {255, 0, 0}, // 10 {255, 127, 127}, - {165, 0, 0}, - {165, 82, 82}, + {204, 0, 0}, + {204, 102, 102}, + {153, 0, 0}, + {153, 76, 76}, {127, 0, 0}, {127, 63, 63}, {76, 0, 0}, {76, 38, 38}, - {38, 0, 0}, - {38, 19, 19}, - {255, 63, 0}, + {255, 63, 0}, // 20 {255, 159, 127}, - {165, 41, 0}, - {165, 103, 82}, + {204, 51, 0}, + {204, 127, 102}, + {153, 38, 0}, + {153, 95, 76}, {127, 31, 0}, {127, 79, 63}, {76, 19, 0}, {76, 47, 38}, - {38, 9, 0}, - {38, 23, 19}, - {255, 127, 0}, + {255, 127, 0}, // 30 {255, 191, 127}, - {165, 82, 0}, - {165, 124, 82}, + {204, 102, 0}, + {204, 153, 102}, + {153, 76, 0}, + {153, 114, 76}, {127, 63, 0}, {127, 95, 63}, {76, 38, 0}, {76, 57, 38}, - {38, 19, 0}, - {38, 28, 19}, - {255, 191, 0}, + {255, 191, 0}, // 40 {255, 223, 127}, - {165, 124, 0}, - {165, 145, 82}, + {204, 153, 0}, + {204, 178, 102}, + {153, 114, 0}, + {153, 133, 76}, {127, 95, 0}, {127, 111, 63}, {76, 57, 0}, {76, 66, 38}, - {38, 28, 0}, - {38, 33, 19}, - {255, 255, 0}, + {255, 255, 0}, // 50 {255, 255, 127}, - {165, 165, 0}, - {165, 165, 82}, + {204, 204, 0}, + {204, 204, 102}, + {152, 152, 0}, + {152, 152, 76}, {127, 127, 0}, {127, 127, 63}, {76, 76, 0}, {76, 76, 38}, - {38, 38, 0}, - {38, 38, 19}, - {191, 255, 0}, + {191, 255, 0}, // 60 {223, 255, 127}, - {124, 165, 0}, - {145, 165, 82}, + {153, 204, 0}, + {178, 204, 102}, + {114, 152, 0}, + {133, 152, 76}, {95, 127, 0}, {111, 127, 63}, {57, 76, 0}, {66, 76, 38}, - {28, 38, 0}, - {33, 38, 19}, - {127, 255, 0}, + {127, 255, 0}, // 70 {191, 255, 127}, - {82, 165, 0}, - {124, 165, 82}, + {102, 204, 0}, + {153, 204, 102}, + {76, 152, 0}, + {114, 152, 76}, {63, 127, 0}, {95, 127, 63}, {38, 76, 0}, {57, 76, 38}, - {19, 38, 0}, - {28, 38, 19}, - {63, 255, 0}, + {63, 255, 0}, // 80 {159, 255, 127}, - {41, 165, 0}, - {103, 165, 82}, + {51, 204, 0}, + {127, 204, 102}, + {38, 152, 0}, + {95, 152, 76}, {31, 127, 0}, {79, 127, 63}, {19, 76, 0}, {47, 76, 38}, - {9, 38, 0}, - {23, 38, 19}, - {0, 255, 0}, + {0, 255, 0}, // 90 {127, 255, 127}, - {0, 165, 0}, - {82, 165, 82}, + {0, 204, 0}, + {102, 204, 102}, + {0, 152, 0}, + {76, 152, 76}, {0, 127, 0}, {63, 127, 63}, {0, 76, 0}, {38, 76, 38}, - {0, 38, 0}, - {19, 38, 19}, - {0, 255, 63}, + {0, 255, 63}, //100 {127, 255, 159}, - {0, 165, 41}, - {82, 165, 103}, + {0, 204, 51}, + {102, 204, 127}, + {0, 152, 38}, + {76, 152, 95}, {0, 127, 31}, {63, 127, 79}, {0, 76, 19}, {38, 76, 47}, - {0, 38, 9}, - {19, 38, 23}, - {0, 255, 127}, + {0, 255, 127}, //110 {127, 255, 191}, - {0, 165, 82}, - {82, 165, 124}, + {0, 204, 102}, + {102, 204, 153}, + {0, 152, 76}, + {76, 152, 114}, {0, 127, 63}, {63, 127, 95}, {0, 76, 38}, {38, 76, 57}, - {0, 38, 19}, - {19, 38, 28}, - {0, 255, 191}, + {0, 255, 191}, //120 {127, 255, 223}, - {0, 165, 124}, - {82, 165, 145}, + {0, 204, 153}, + {102, 204, 178}, + {0, 152, 114}, + {76, 152, 133}, {0, 127, 95}, {63, 127, 111}, {0, 76, 57}, {38, 76, 66}, - {0, 38, 28}, - {19, 38, 33}, - {0, 255, 255}, + {0, 255, 255}, //130 {127, 255, 255}, - {0, 165, 165}, - {82, 165, 165}, + {0, 204, 204}, + {102, 204, 204}, + {0, 152, 152}, + {76, 152, 152}, {0, 127, 127}, {63, 127, 127}, {0, 76, 76}, {38, 76, 76}, - {0, 38, 38}, - {19, 38, 38}, - {0, 191, 255}, + {0, 191, 255}, //140 {127, 223, 255}, - {0, 124, 165}, - {82, 145, 165}, + {0, 153, 204}, + {102, 178, 204}, + {0, 114, 152}, + {76, 133, 152}, {0, 95, 127}, {63, 111, 127}, {0, 57, 76}, {38, 66, 76}, - {0, 28, 38}, - {19, 33, 38}, - {0, 127, 255}, + {0, 127, 255}, //150 {127, 191, 255}, - {0, 82, 165}, - {82, 124, 165}, + {0, 102, 204}, + {102, 153, 204}, + {0, 76, 152}, + {76, 114, 152}, {0, 63, 127}, {63, 95, 127}, {0, 38, 76}, {38, 57, 76}, - {0, 19, 38}, - {19, 28, 38}, - {0, 63, 255}, + {0, 63, 255}, //160 {127, 159, 255}, - {0, 41, 165}, - {82, 103, 165}, + {0, 51, 204}, + {102, 127, 204}, + {0, 38, 152}, + {76, 95, 152}, {0, 31, 127}, {63, 79, 127}, {0, 19, 76}, {38, 47, 76}, - {0, 9, 38}, - {19, 23, 38}, - {0, 0, 255}, + {0, 0, 255}, //170 {127, 127, 255}, - {0, 0, 165}, - {82, 82, 165}, + {0, 0, 204}, + {102, 102, 204}, + {0, 0, 152}, + {76, 76, 152}, {0, 0, 127}, {63, 63, 127}, {0, 0, 76}, {38, 38, 76}, - {0, 0, 38}, - {19, 19, 38}, - {63, 0, 255}, + {63, 0, 255}, //180 {159, 127, 255}, - {41, 0, 165}, - {103, 82, 165}, + {51, 0, 204}, + {127, 102, 204}, + {38, 0, 152}, + {95, 76, 152}, {31, 0, 127}, {79, 63, 127}, {19, 0, 76}, {47, 38, 76}, - {9, 0, 38}, - {23, 19, 38}, - {127, 0, 255}, + {127, 0, 255}, //190 {191, 127, 255}, - {82, 0, 165}, - {124, 82, 165}, + {102, 0, 204}, + {153, 102, 204}, + {76, 0, 152}, + {114, 76, 152}, {63, 0, 127}, {95, 63, 127}, {38, 0, 76}, {57, 38, 76}, - {19, 0, 38}, - {28, 19, 38}, - {191, 0, 255}, + {191, 0, 255}, //200 {223, 127, 255}, - {124, 0, 165}, - {145, 82, 165}, + {153, 0, 204}, + {178, 102, 204}, + {114, 0, 152}, + {133, 76, 152}, {95, 0, 127}, {111, 63, 127}, {57, 0, 76}, {66, 38, 76}, - {28, 0, 38}, - {33, 19, 38}, - {255, 0, 255}, + {255, 0, 255}, //210 {255, 127, 255}, - {165, 0, 165}, - {165, 82, 165}, + {204, 0, 204}, + {204, 102, 204}, + {152, 0, 152}, + {152, 76, 152}, {127, 0, 127}, {127, 63, 127}, {76, 0, 76}, {76, 38, 76}, - {38, 0, 38}, - {38, 19, 38}, - {255, 0, 191}, + {255, 0, 191}, //220 {255, 127, 223}, - {165, 0, 124}, - {165, 82, 145}, + {204, 0, 153}, + {204, 102, 178}, + {152, 0, 114}, + {152, 76, 133}, {127, 0, 95}, {127, 63, 111}, {76, 0, 57}, {76, 38, 66}, - {38, 0, 28}, - {38, 19, 33}, - {255, 0, 127}, + {255, 0, 127}, //230 {255, 127, 191}, - {165, 0, 82}, - {165, 82, 124}, + {204, 0, 102}, + {204, 102, 153}, + {152, 0, 76}, + {152, 76, 114}, {127, 0, 63}, {127, 63, 95}, {76, 0, 38}, {76, 38, 57}, - {38, 0, 19}, - {38, 19, 28}, - {255, 0, 63}, + {255, 0, 63}, //240 {255, 127, 159}, - {165, 0, 41}, - {165, 82, 103}, + {204, 0, 51}, + {204, 102, 127}, + {152, 0, 38}, + {152, 76, 95}, {127, 0, 31}, {127, 63, 79}, {76, 0, 19}, {76, 38, 47}, - {38, 0, 9}, - {38, 19, 23}, - {26, 26, 26}, - {51, 51, 51}, - {102, 102, 102}, - {153, 153, 153}, - {204, 204, 204}, + {51, 51, 51}, //250 + {91, 91, 91}, + {132, 132, 132}, + {173, 173, 173}, + {214, 214, 214}, {255, 255, 255}} ; diff --git a/DxfConst.h b/DxfConst.h index 7ccc700..be210d6 100644 --- a/DxfConst.h +++ b/DxfConst.h @@ -25,6 +25,8 @@ const int ENT_HIDE = 1 ; // colori speciali const int COL_BYBLOCK = 0 ; const int COL_BYLAYER = 256 ; +// colore di default +const int COL_DEFAULT = 7 ; // flag per splines const int SPL_CLOSED = 1 ; const int SPL_PERIODIC = 2 ; @@ -40,4 +42,10 @@ const std::string FLAGS_INFO = "FLG" ; const std::string SCALE_INFO = "SCA" ; const std::string ROTAT_INFO = "ROT" ; const std::string VTEXT_INFO = "VEX" ; - +// nome layer di default +const std::string LAY_DEFAULT = "0" ; +// tipo di linea di default +const std::string LINETYPE_DEFAULT = "CONTINUOUS" ; +// costanti di approssimazione per curve di Bezier e eliche +const double BEZ_LIN_APPROX = 0.01 ; +const double BEZ_ANG_APPROX_DEG = 5.0 ; diff --git a/EgtExchange.rc b/EgtExchange.rc index 810a4b0..ed6ffd3 100644 Binary files a/EgtExchange.rc and b/EgtExchange.rc differ diff --git a/EgtExchange.vcxproj b/EgtExchange.vcxproj index 5dbd56b..7496ed6 100644 --- a/EgtExchange.vcxproj +++ b/EgtExchange.vcxproj @@ -181,6 +181,9 @@ copy $(TargetPath) \EgtProg\Dll64 + + + @@ -188,6 +191,8 @@ copy $(TargetPath) \EgtProg\Dll64 + + @@ -209,6 +214,8 @@ copy $(TargetPath) \EgtProg\Dll64 + + diff --git a/EgtExchange.vcxproj.filters b/EgtExchange.vcxproj.filters index f3def4d..2bed90f 100644 --- a/EgtExchange.vcxproj.filters +++ b/EgtExchange.vcxproj.filters @@ -48,6 +48,21 @@ File di intestazione + + File di intestazione + + + File di intestazione + + + File di intestazione + + + File di intestazione + + + File di intestazione + @@ -77,6 +92,12 @@ File di origine + + File di origine + + + File di origine + diff --git a/ExcExecutor.cpp b/ExcExecutor.cpp index e8cb4a2..5d8fa22 100644 --- a/ExcExecutor.cpp +++ b/ExcExecutor.cpp @@ -17,6 +17,8 @@ #include "DllMain.h" #include "/EgtDev/Include/EgnStringUtils.h" #include "/EgtDev/Include/EgnCmdParser.h" +#include "/EgtDev/Include/EExExportStl.h" +#include "/EgtDev/Include/EExExportDxf.h" #include "/EgtDev/Include/EExImportStl.h" #include "/EgtDev/Include/EExImportDxf.h" @@ -34,7 +36,9 @@ CreateExcExecutor( void) ExcExecutor::ExcExecutor( void) { // assegno chiavi a funzioni di esecuzione - m_ExecMgr.Init( 4) ; + m_ExecMgr.Init( 8) ; + m_ExecMgr.Insert( "EXPORTSTL", &ExcExecutor::ExecuteExportStl) ; + m_ExecMgr.Insert( "EXPORTDXF", &ExcExecutor::ExecuteExportDxf) ; m_ExecMgr.Insert( "IMPORTSTL", &ExcExecutor::ExecuteImportStl) ; m_ExecMgr.Insert( "IMPORTDXF", &ExcExecutor::ExecuteImportDxf) ; } @@ -78,6 +82,62 @@ ExcExecutor::SetGeomDB( IGeomDB* pGdb) return ( m_pGDB != nullptr) ; } +//---------------------------------------------------------------------------- +bool +ExcExecutor::ExecuteExportStl( const string& sCmd2, const STRVECTOR& vsParams) +{ + // 2 parametri : Id del gruppo, nome del file + if ( vsParams.size() != 2) + return false ; + // recupero l'Id + int nId = m_pParser->GetIdParam( vsParams[0]) ; + if ( nId == CMD_ID_ERROR) + return false ; + // eventuale conversione di token nel nome file + string sFile = vsParams[1] ; + m_pParser->DirReplace( sFile) ; + // preparo l'esportatore + IExportStl* pExpStl = CreateExportStl() ; + if ( pExpStl == nullptr) { + LOG_ERROR( GetEExLogger(), "Error : CreateExportStl") + return false ; + } + // eseguo l'esportazione + bool bOk = pExpStl->Export( m_pGDB, nId, sFile) ; + // cancello l'esportatore + delete pExpStl ; + + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +ExcExecutor::ExecuteExportDxf( const string& sCmd2, const STRVECTOR& vsParams) +{ + // 2 parametri : Id del gruppo, nome del file + if ( vsParams.size() != 2) + return false ; + // recupero l'Id + int nId = m_pParser->GetIdParam( vsParams[0]) ; + if ( nId == CMD_ID_ERROR) + return false ; + // eventuale conversione di token nel nome file + string sFile = vsParams[1] ; + m_pParser->DirReplace( sFile) ; + // preparo l'esportatore + IExportDxf* pExpDxf = CreateExportDxf() ; + if ( pExpDxf == nullptr) { + LOG_ERROR( GetEExLogger(), "Error : CreateExportDxf") + return false ; + } + // eseguo l'esportazione + bool bOk = pExpDxf->Export( m_pGDB, nId, sFile) ; + // cancello l'esportatore + delete pExpDxf ; + + return bOk ; +} + //---------------------------------------------------------------------------- bool ExcExecutor::ExecuteImportStl( const string& sCmd2, const STRVECTOR& vsParams) diff --git a/ExcExecutor.h b/ExcExecutor.h index 8c65537..df1d310 100644 --- a/ExcExecutor.h +++ b/ExcExecutor.h @@ -35,6 +35,8 @@ class ExcExecutor : public IExcExecutor ExcExecutor( void) ; private : + bool ExecuteExportStl( const std::string& sCmd2, const STRVECTOR& vsParams) ; + bool ExecuteExportDxf( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool ExecuteImportStl( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool ExecuteImportDxf( const std::string& sCmd2, const STRVECTOR& vsParams) ; diff --git a/ExportDxf.cpp b/ExportDxf.cpp new file mode 100644 index 0000000..857f746 --- /dev/null +++ b/ExportDxf.cpp @@ -0,0 +1,1000 @@ +//---------------------------------------------------------------------------- +// EgalTech 2014-2014 +//---------------------------------------------------------------------------- +// File : ExportDxf.cpp Data : 07.08.14 Versione : 1.5h2 +// Contenuto : Implementazione della classe per l'esportazione in formato DXF. +// +// +// +// Modifiche : 07.08.14 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "ExportDxf.h" +#include "DxfConst.h" +#include "DxfColors.h" +#include "DllMain.h" +#include "/EgtDev/Include/EGkGeomDB.h" +#include "/EgtDev/Include/EGkGdbIterator.h" +#include "/EgtDev/Include/EGkGeoPoint3d.h" +#include "/EgtDev/Include/EGkGeoVector3d.h" +#include "/EgtDev/Include/EGkCurveLine.h" +#include "/EgtDev/Include/EGkCurveArc.h" +#include "/EgtDev/Include/EGkCurveBezier.h" +#include "/EgtDev/Include/EGkCurveComposite.h" +#include "/EgtDev/Include/EgkCurveAux.h" +#include "/EgtDev/Include/EGkPolyLine.h" +#include "/EgtDev/Include/EGkSurfTriMesh.h" +#include "/EgtDev/Include/EgkStringUtils3d.h" +#include "/EgtDev/Include/EgnStringUtils.h" +#include "/EgtDev/Include/EgnStringConverter.h" +#include "/EgtDev/Include/EgtPointerOwner.h" + +using namespace std ; + +//---------------------------------------------------------------------------- +IExportDxf* +CreateExportDxf( void) +{ + return static_cast ( new(nothrow) ExportDxf) ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::SetOptions( int nFilter, int nFlag) +{ + m_nFilter = nFilter ; + m_bCompoundLayer = ( nFlag & EEXFLAG_COMP_LAYER) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::Export( IGeomDB* pGDB, int nId, const string& sFile) +{ + // verifico il DB geometrico + if ( pGDB == nullptr) { + LOG_ERROR( GetEExLogger(), "ExportDxf : Error on GeomDB") + return false ; + } + + // verifico l'Id dell'oggetto da esportare + if ( ! pGDB->ExistsObj( nId)) { + LOG_ERROR( GetEExLogger(), "ExportDxf : Error on Id") + return false ; + } + + // apro il file di testo in scrittura + m_OutFile.open( stringtoW( sFile), ios::out, _SH_DENYWR) ; + if ( ! m_OutFile.good()) { + LOG_ERROR( GetEExLogger(), "ExportDxf : Error on open file") + return false ; + } + + bool bOk = true ; + + // scrivo la sezione di intestazione + if ( ! ExportHeader( pGDB, nId)) + bOk = false ; + + // scrivo la sezione tavole + if ( ! ExportTables( pGDB, nId)) + bOk = false ; + + // scrivo la sezione entità + if ( ! ExportEntities( pGDB, nId)) + bOk = false ; + + // terminazione file + if ( ! WriteItem( 0, "EOF")) + bOk = false ; + + // chiudo il file + if ( ! m_OutFile.good() || ! m_OutFile.is_open()) + bOk = false ; + if ( m_OutFile.is_open()) + m_OutFile.close() ; + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportHeader( IGeomDB* pGDB, int nId) +{ + // intestazione sezione header + if ( ! WriteItem( 0, "SECTION") || + ! WriteItem( 2, "HEADER")) + return false ; + + // versione DXF + if ( ! WriteItem( 9, "$ACADVER") || + ! WriteItem( 1, "AC1009")) + return false ; + + // estensione + BBox3d b3Glob ; + if ( ! pGDB->GetGlobalBBox( nId, b3Glob)) + return false ; + if ( ! WriteItem( 9, "$EXTMIN") || + ! WriteItem( 10, b3Glob.GetMin().x) || + ! WriteItem( 20, b3Glob.GetMin().y) || + ! WriteItem( 30, b3Glob.GetMin().z)) + return false ; + if ( ! WriteItem( 9, "$EXTMAX") || + ! WriteItem( 10, b3Glob.GetMax().x) || + ! WriteItem( 20, b3Glob.GetMax().y) || + ! WriteItem( 30, b3Glob.GetMax().z)) + return false ; + + // terminazione sezione header + if ( ! WriteItem( 0, "ENDSEC")) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportTables( IGeomDB* pGDB, int nId) +{ + // intestazione sezione tables + if ( ! WriteItem( 0, "SECTION") || + ! WriteItem( 2, "TABLES")) + return false ; + + // scrittura tavola per tipi di linea + if ( ! WriteLinetypesTable( pGDB, nId)) + return false ; + + // scrittura tavola per i layers + if ( ! WriteLayersTable( pGDB, nId)) + return false ; + + // terminazione sezione tables + if ( ! WriteItem( 0, "ENDSEC")) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteLinetypesTable( IGeomDB* pGDB, int nId) +{ + // scrittura intestazione della tavola + if ( ! WriteItem( 0, "TABLE") || + ! WriteItem( 2, "LTYPE")) + return false ; + // un solo tipo di linea + if ( ! WriteItem( 70, 1)) + return false ; + // tipo di linea continuo + if ( ! WriteItem( 0, "LTYPE")) + return false ; + if ( ! WriteItem( 2, "CONTINUOUS")) + return false ; + if ( ! WriteItem( 70, 0)) + return false ; + if ( ! WriteItem( 3, "Solid line")) + return false ; + if ( ! WriteItem( 72, 65)) + return false ; + if ( ! WriteItem( 73, 0)) + return false ; + if ( ! WriteItem( 40, 0.0)) + return false ; + // scrittura terminazione della tavola + if ( ! WriteItem( 0, "ENDTAB")) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteLayersTable( IGeomDB* pGDB, int nId) +{ + // ciclo di ricerca dei layer + // creo un iteratore + PtrOwner pIter( CreateGdbIterator( pGDB)) ; + if ( ! ::IsValid( pIter)) + return false ; + pIter->GoTo( nId) ; + // eseguo la ricerca + LAYDATVECTOR vLayDat ; + if ( ! FindLayers( *pIter, LAY_DEFAULT, vLayDat)) + return false ; + + // scrittura intestazione della tavola + if ( ! WriteItem( 0, "TABLE") || + ! WriteItem( 2, "LAYER")) + return false ; + // numero di layer + int nLayNbr = int( vLayDat.size()) ; + if ( ! WriteItem( 70, nLayNbr)) + return false ; + // scrittura dei layers + for ( int i = 0 ; i < nLayNbr ; ++i) { + if ( ! WriteLayer( vLayDat[i].first, 0, vLayDat[i].second, LINETYPE_DEFAULT)) + return false ; + } + // scrittura terminazione della tavola + if ( ! WriteItem( 0, "ENDTAB")) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::FindLayers( const IGdbIterator& iIter, const string& sLay, LAYDATVECTOR& vLayDat) +{ + // se non è un gruppo, esco subito + if ( iIter.GetGdbType() != GDB_TY_GROUP) + return true ; + + // aggiorno nome layer + bool bExactLay ; + string sNewLay = UpdateLayerName( iIter, sLay, &bExactLay) ; + // recupero il colore corrente + Color cCol ; + int nCol ; + if ( iIter.GetCalcMaterial( cCol)) + ColorToACI( cCol, nCol) ; + // se layer non presente, lo aggiungo al vettore dei layer + bool bFound = false ; + for ( int i = 0 ; ! bFound && i < int( vLayDat.size()) ; ++ i) { + string s1 = vLayDat[i].first ; + string s2 = sNewLay ; + if ( ToUpper( s1) == ToUpper( s2)) { + bFound = true ; + // se è il nome esatto, aggiorno il colore + if ( bExactLay) + vLayDat[i].second = nCol ; + } + } + if ( ! bFound) + vLayDat.push_back( make_pair( sNewLay, nCol)) ; + // scandisco il gruppo alla ricerca di sottogruppi + PtrOwner pIter( CreateGdbIterator( iIter.GetGDB())) ; + if ( ! ::IsValid( pIter)) + return false ; + bool bOk = true ; + for ( bool bNext = pIter->GoToFirstInGroup( iIter) ; + bNext ; + bNext = pIter->GoToNext()) { + if ( ! FindLayers( *pIter, sNewLay, vLayDat)) + bOk = false ; + } + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteLayer( const string& sLay, int nFlag, int nCol, const string& sLineType) +{ + // intestazione layer + if ( ! WriteItem( 0, "LAYER")) + return false ; + // nome layer + if ( ! WriteItem( 2, sLay)) + return false ; + // flag + if ( ! WriteItem( 70, nFlag)) + return false ; + // colore + if ( ! WriteItem( 62, nCol)) + return false ; + // tipo linea + if ( ! WriteItem( 6, sLineType)) + return false ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportEntities( IGeomDB* pGDB, int nId) +{ + // intestazione sezione entità + if ( ! WriteItem( 0, "SECTION") || + ! WriteItem( 2, "ENTITIES")) + return false ; + + // creo un iteratore + PtrOwner pIter( CreateGdbIterator( pGDB)) ; + if ( ! ::IsValid( pIter)) + return false ; + pIter->GoTo( nId) ; + // esporto l'oggetto e i suoi eventuali figli + if ( ! ExportGdbObject( *pIter, LAY_DEFAULT)) + return false ; + + // terminazione sezione entità + if ( ! WriteItem( 0, "ENDSEC")) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportGdbObject( const IGdbIterator& iIter, const string& sLay) +{ + // recupero il tipo dell'oggetto + int nGdbType = iIter.GetGdbType() ; + // se oggetto geometrico + if ( nGdbType == GDB_TY_GEO) { + // recupero l'oggetto geometrico + const IGeoObj* pGeoObj =(const_cast(&iIter))->GetGeoObj() ; + if ( pGeoObj == nullptr) + return true ; + // recupero il riferimento globale dell'oggetto + Frame3d frFrame ; + if ( ! iIter.GetGlobFrame( frFrame)) + return false ; + // recupero il livello dell'oggetto + int nLev = GDB_LV_USER ; + iIter.GetCalcLevel( nLev) ; + // recupero il modo dell'oggetto + int nMode = GDB_MD_STD ; + iIter.GetCalcMode( nMode) ; + // recupero lo stato dell'oggetto + int nStat = GDB_ST_ON ; + iIter.GetCalcStatus( nStat) ; + // se il filtro lo abilita + if ( TestFilter( nLev, nMode, nStat)) { + // recupero colore (trasformato in formato ACI) + int nCol = COL_DEFAULT ; + Color cCol ; + if ( ( m_bColorByLayer && iIter.GetMaterial( cCol)) || + ( ! m_bColorByLayer && iIter.GetCalcMaterial( cCol))) + ColorToACI( cCol, nCol) ; + // emetto l'oggetto + switch ( pGeoObj->GetType()) { + case GEO_PNT3D : + if ( ! ExportPoint( sLay, nCol, pGeoObj, frFrame)) + return false ; + break ; + case GEO_VECT3D : + if ( ! ExportVector( sLay, nCol, pGeoObj, frFrame)) + return false ; + break ; + case CRV_LINE : + if ( ! ExportLine( sLay, nCol, pGeoObj, frFrame)) + return false ; + break ; + case CRV_ARC : + if ( ! ExportArc( sLay, nCol, pGeoObj, frFrame)) + return false ; + break ; + case CRV_BEZ : + if ( ! ExportCrvBezier( sLay, nCol, pGeoObj, frFrame)) + return false ; + break ; + case CRV_COMPO : + if ( ! ExportCrvCompo( sLay, nCol, pGeoObj, frFrame)) + return false ; + break ; + case SRF_TRIMESH : + if ( ! ExportSTM( sLay, nCol, pGeoObj, frFrame)) + return false ; + break ; + } + } + return true ; + } + // se gruppo di oggetti + else if ( nGdbType == GDB_TY_GROUP) { + // esporto il gruppo + return ExportGdbGroup( iIter, sLay) ; + } + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportGdbGroup( const IGdbIterator& iIter, const string& sLay) +{ + // creo un iteratore + PtrOwner pIter( CreateGdbIterator( iIter.GetGDB())) ; + if ( ! ::IsValid( pIter)) + return false ; + // aggiorno nome layer + string sNewLay = UpdateLayerName( iIter, sLay) ; + // scandisco il gruppo + bool bOk = true ; + for ( bool bNext = pIter->GoToFirstInGroup( iIter) ; + bNext ; + bNext = pIter->GoToNext()) { + if ( ! ExportGdbObject( *pIter, sNewLay)) + bOk = false ; + } + + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportPoint( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) +{ + // verifico oggetto + const IGeoPoint3d* pGPnt = GetGeoPoint3d( pGeoObj) ; + if ( pGPnt == nullptr) + return false ; + // scrittura del punto + return WritePoint( sLay, nCol, pGPnt->GetPoint(), V_NULL, frFrame) ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportVector( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) +{ + // verifico oggetto + const IGeoVector3d* pGVect = GetGeoVector3d( pGeoObj) ; + if ( pGVect == nullptr) + return false ; + // scrittura del vettore con punto base + return WritePoint( sLay, nCol, pGVect->GetBase(), pGVect->GetVector(), frFrame) ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportLine( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) +{ + // verifico oggetto + const ICurveLine* pLine = GetCurveLine( pGeoObj) ; + if ( pLine == nullptr) + return false ; + // scrivo l'entità + return WriteLine( sLay, nCol, pLine, frFrame) ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportArc( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) +{ + // verifico oggetto + const ICurveArc* pArc = GetCurveArc( pGeoObj) ; + if ( pArc == nullptr) + return false ; + // se è un'elica + if ( ! pArc->IsFlat()) { + // esporto come polilinea 3d + return WriteCurve3d( sLay, nCol, pArc, frFrame) ; + } + // se circonferenza + if ( pArc->IsACircle()) { + // esporto come cerchio + return WriteCircle( sLay, nCol, pArc, frFrame) ; + } + // altrimenti arco 2d + return WriteArc( sLay, nCol, pArc, frFrame) ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportCrvBezier( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) +{ + // deve essere una curva di Bezier + const ICurveBezier* pCBez = GetCurveBezier( pGeoObj) ; + if ( pCBez == nullptr) + return false ; + // esporto come polilinea 3d + return WriteCurve3d( sLay, nCol, pCBez, frFrame) ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportCrvCompo( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) +{ + // deve essere una curva composita + const ICurveComposite* pCC = GetCurveComposite( pGeoObj) ; + if ( pCC == nullptr) + return false ; + // esporto come polilinea 3d + return WriteCurve3d( sLay, nCol, pCC, frFrame) ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ExportSTM( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) +{ + // deve essere una superficie trimesh + const ISurfTriMesh* pSTM = GetSurfTriMesh( pGeoObj) ; + if ( pSTM == nullptr) + return false ; + // identificativo entità + if ( ! WriteItem( 0, "POLYLINE")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // colore + if ( ! WriteItem( 62, nCol)) + return false ; + // flag segnalazione entità successive dipendenti (vertex) + if ( ! WriteItem( 66, 1)) + return false ; + // punto inutile ma obbligatorio + if ( ! WriteItem( 10, 0) || + ! WriteItem( 20, 0) || + ! WriteItem( 30, 0)) + return false ; + // flag (polyface mesh 3d) + if ( ! WriteItem( 70, 64)) + return false ; + // numero di vertici + if ( ! WriteItem( 71, pSTM->GetVertexNum())) + return false ; + // numero di facce + if ( ! WriteItem( 72, pSTM->GetTriangleNum())) + return false ; + // ciclo sui vertici + Point3d ptP ; + for ( int nId = pSTM->GetFirstVertex( ptP) ; + nId != SVT_NULL ; + nId = pSTM->GetNextVertex( nId, ptP)) { + // entità vertice + if ( ! WriteItem( 0, "VERTEX")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // punto corrente + ptP.ToGlob( frFrame) ; + if ( ! WriteItem( 10, ptP.x) || + ! WriteItem( 20, ptP.y) || + ! WriteItem( 30, ptP.z)) + return false ; + // flag (3d polygon mesh + polyface mesh vertex) + if ( ! WriteItem( 70, 64 + 128)) + return false ; + } + // ciclo sui triangoli + int nIdVert[3] ; + for ( int nId = pSTM->GetFirstTriangle( nIdVert) ; + nId != SVT_NULL ; + nId = pSTM->GetNextTriangle( nId, nIdVert)) { + // entità vertice + if ( ! WriteItem( 0, "VERTEX")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // colore (unico colore riconosciuto) + if ( ! WriteItem( 62, nCol)) + return false ; + // punto inutile ma obbligatorio + if ( ! WriteItem( 10, 0) || + ! WriteItem( 20, 0) || + ! WriteItem( 30, 0)) + return false ; + // flag (polyface mesh vertex) + if ( ! WriteItem( 70, 128)) + return false ; + // indici dei vertici (1-based) + if ( ! WriteItem( 71, nIdVert[0] + 1) || + ! WriteItem( 72, nIdVert[1] + 1) || + ! WriteItem( 73, nIdVert[2] + 1)) + return false ; + } + // entità termine dei vertici + if ( ! WriteItem( 0, "SEQEND")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WritePoint( const string& sLay, int nCol, const Point3d& ptP, const Vector3d& vtV, const Frame3d& frFrame) +{ + // identificativo entità + if ( ! WriteItem( 0, "POINT")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // colore + if ( ! WriteItem( 62, nCol)) + return false ; + // punto + Point3d ptOut = ptP ; + ptOut.ToGlob( frFrame) ; + if ( ! WriteItem( 10, ptOut.x) || + ! WriteItem( 20, ptOut.y) || + ! WriteItem( 30, ptOut.z)) + return false ; + // eventuale versore estrusione e spessore + if ( ! vtV.IsSmall()) { + double dTh = vtV.Len() ; + Vector3d vtExtr = vtV / dTh ; + if ( ! WriteItem( 39, dTh) || + ! WriteItem( 210, vtExtr.x) || + ! WriteItem( 220, vtExtr.y) || + ! WriteItem( 230, vtExtr.z)) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteLine( const string& sLay, int nCol, const ICurveLine* pLine, const Frame3d& frFrame) +{ + // verifico validità linea + if ( pLine == nullptr) + return false ; + // identificativo entità + if ( ! WriteItem( 0, "LINE")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // colore + if ( ! WriteItem( 62, nCol)) + return false ; + // punto iniziale + Point3d ptStart = pLine->GetStart() ; + ptStart.ToGlob( frFrame) ; + if ( ! WriteItem( 10, ptStart.x) || + ! WriteItem( 20, ptStart.y) || + ! WriteItem( 30, ptStart.z)) + return false ; + // punto finale + Point3d ptEnd = pLine->GetEnd() ; + ptEnd.ToGlob( frFrame) ; + if ( ! WriteItem( 11, ptEnd.x) || + ! WriteItem( 21, ptEnd.y) || + ! WriteItem( 31, ptEnd.z)) + return false ; + // vettore estrusione !!! DA FARE + // spessore !!! DA FARE + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteCircle( const string& sLay, int nCol, const ICurveArc* pArc, const Frame3d& frFrame) +{ + // verifico validità arco + if ( pArc == nullptr) + return false ; + // calcolo riferimento OCS + Vector3d vtN = pArc->GetNormVersor() ; + vtN.ToGlob( frFrame) ; + Frame3d frOCS ; + frOCS.Set( ORIG, vtN) ; + // identificativo entità + if ( ! WriteItem( 0, "CIRCLE")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // colore + if ( ! WriteItem( 62, nCol)) + return false ; + // centro + Point3d ptCen = pArc->GetCenter() ; + ptCen.LocToLoc( frFrame, frOCS) ; + if ( ! WriteItem( 10, ptCen.x) || + ! WriteItem( 20, ptCen.y) || + ! WriteItem( 30, ptCen.z)) + return false ; + // raggio + double dRad = pArc->GetRadius() ; + if ( ! WriteItem( 40, dRad)) + return false ; + // vettore estrusione + if ( ! WriteItem( 210, vtN.x) || + ! WriteItem( 220, vtN.y) || + ! WriteItem( 230, vtN.z)) + return false ; + // spessore !!! DA FARE + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteArc( const string& sLay, int nCol, const ICurveArc* pArc, const Frame3d& frFrame) +{ + // calcolo riferimento OCS + Vector3d vtN = pArc->GetNormVersor() ; + vtN.ToGlob( frFrame) ; + Frame3d frOCS ; + frOCS.Set( ORIG, vtN) ; + // identificativo entità + if ( ! WriteItem( 0, "ARC")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // colore + if ( ! WriteItem( 62, nCol)) + return false ; + // centro + Point3d ptCen = pArc->GetCenter() ; + ptCen.LocToLoc( frFrame, frOCS) ; + if ( ! WriteItem( 10, ptCen.x) || + ! WriteItem( 20, ptCen.y) || + ! WriteItem( 30, ptCen.z)) + return false ; + // angoli iniziale e finale (archi sempre CCW) + double dStartAngDeg, dEndAngDeg ; + Vector3d vtS = pArc->GetStartVersor() ; + vtS.LocToLoc( frFrame, frOCS) ; + vtS.ToSpherical( nullptr, nullptr, &dStartAngDeg) ; + double dCenAngDeg = pArc->GetAngCenter() ; + dEndAngDeg = dStartAngDeg + dCenAngDeg ; + if ( dCenAngDeg < 0) + swap( dStartAngDeg, dEndAngDeg) ; + if ( ! WriteItem( 50, dStartAngDeg) || + ! WriteItem( 51, dEndAngDeg)) + return false ; + // raggio + double dRad = pArc->GetRadius() ; + if ( ! WriteItem( 40, dRad)) + return false ; + // vettore estrusione + if ( ! WriteItem( 210, vtN.x) || + ! WriteItem( 220, vtN.y) || + ! WriteItem( 230, vtN.z)) + return false ; + // spessore !!! DA FARE + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteCurve3d( const string& sLay, int nCol, const ICurve* pCrv, const Frame3d& frFrame) +{ + // verifico validità curva + if ( pCrv == nullptr) + return false ; + // trasformo in polilinea + PolyLine PL ; + if ( ! pCrv->ApproxWithLines( BEZ_LIN_APPROX, BEZ_ANG_APPROX_DEG, PL)) + return false ; + // esporto come polyline 3d + if ( ! WriteItem( 0, "POLYLINE")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // colore + if ( ! WriteItem( 62, nCol)) + return false ; + // flag segnalazione entità successive dipendenti (vertex) + if ( ! WriteItem( 66, 1)) + return false ; + // punto inutile ma obbligatorio + if ( ! WriteItem( 10, 0) || + ! WriteItem( 20, 0) || + ! WriteItem( 30, 0)) + return false ; + // flag (3d) + if ( ! WriteItem( 70, 8)) + return false ; + // emetto i vertici + Point3d ptP ; + for ( bool bPnt = PL.GetFirstPoint( ptP) ; + bPnt ; + bPnt = PL.GetNextPoint( ptP)) { + // entità vertice + if ( ! WriteItem( 0, "VERTEX")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + // punto corrente + ptP.ToGlob( frFrame) ; + if ( ! WriteItem( 10, ptP.x) || + ! WriteItem( 20, ptP.y) || + ! WriteItem( 30, ptP.z)) + return false ; + // flag (3d polyline) + if ( ! WriteItem( 70, 32)) + return false ; + } + // entità termine dei vertici + if ( ! WriteItem( 0, "SEQEND")) + return false ; + // layer + if ( ! WriteItem( 8, sLay)) + return false ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::TestFilter( int nLev, int nMode, int nStat) +{ + if ( ( nLev == GDB_LV_USER && ( m_nFilter & EEXFLT_LEVUSER) == 0) || + ( nLev == GDB_LV_SYSTEM && ( m_nFilter & EEXFLT_LEVSYSTEM) == 0) || + ( nLev == GDB_LV_TEMP && ( m_nFilter & EEXFLT_LEVTEMP) == 0)) + return false ; + if ( ( nMode == GDB_MD_STD && ( m_nFilter & EEXFLT_MODESTD) == 0) || + ( nMode == GDB_MD_LOCKED && ( m_nFilter & EEXFLT_MODELOCKED) == 0) || + ( nMode == GDB_MD_HIDDEN && ( m_nFilter & EEXFLT_MODEHIDDEN) == 0)) + return false ; + if ( ( nStat == GDB_ST_OFF && ( m_nFilter & EEXFLT_STAOFF) == 0) || + ( nStat == GDB_ST_ON && ( m_nFilter & EEXFLT_STAON) == 0) || + ( nStat == GDB_ST_SEL && ( m_nFilter & EEXFLT_STASEL) == 0)) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteItem( int nCode, int nVal) +{ + try { + m_OutFile << ( nCode < 10 ? " " : nCode < 100 ? " " : "") << ToString( nCode) << endl ; + m_OutFile << ToString( nVal) << endl ; + } + catch( ...) { return false ; } + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteItem( int nCode, double dVal, int nPrec) +{ + try { + m_OutFile << ( nCode < 10 ? " " : nCode < 100 ? " " : "") << ToString( nCode) << endl ; + m_OutFile << ToString( dVal, nPrec) << endl ; + } + catch( ...) { return false ; } + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::WriteItem( int nCode, const string& sVal) +{ + try { + m_OutFile << ( nCode < 10 ? " " : nCode < 100 ? " " : "") << ToString( nCode) << endl ; + m_OutFile << sVal << endl ; + } + catch( ...) { return false ; } + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportDxf::ColorToACI( const Color& cCol, int& nColor) +{ + // recupero RGB + int nRed = cCol.GetIntRed() ; + int nGreen = cCol.GetIntGreen() ; + int nBlue = cCol.GetIntBlue() ; + + // colori speciali (con indice 1...9) + if ( nRed == MAX_RGB && nGreen == 0 && nBlue == 0) { + nColor = 1 ; // rosso + return true ; + } + else if ( nRed == MAX_RGB && nGreen == MAX_RGB && nBlue == 0) { + nColor = 2 ; // giallo + return true ; + } + else if ( nRed == 0 && nGreen == MAX_RGB && nBlue == 0) { + nColor = 3 ; // verde + return true ; + } + else if ( nRed == 0 && nGreen == MAX_RGB && nBlue == MAX_RGB) { + nColor = 4 ; // ciano + return true ; + } + else if ( nRed == 0 && nGreen == 0 && nBlue == MAX_RGB) { + nColor = 5 ; // blu + return true ; + } + else if ( nRed == MAX_RGB && nGreen == 0 && nBlue == MAX_RGB) { + nColor = 6 ; // magenta + return true ; + } + else if ( nRed == MAX_RGB && nGreen == MAX_RGB && nBlue == MAX_RGB) { + nColor = 7 ; // bianco + return true ; + } + else if ( nRed == 128 && nGreen == 128 && nBlue == 128) { + nColor = 8 ; // grigio + return true ; + } + else if ( nRed == 192 && nGreen == 192 && nBlue == 192) { + nColor = 9 ; // grigio chiaro + return true ; + } + + // calcolo HSV + int nH = max( max( nRed, nGreen), nBlue) ; + int nL = min( min( nRed, nGreen), nBlue) ; + double dValue = nH / double( MAX_RGB) ; + double dSat = 0.0 ; + if ( nH > 0) + dSat = ( nH - nL) / double( nH) ; + double dHue = 0.0 ; + if ( nH == nL) + dHue = 0.0 ; + else if ( nH == nRed) { + dHue = 0.0 + ( 60.0 * ( nGreen - nBlue) / double( nH - nL)) ; + if ( dHue < 0) + dHue += 360 ; + } + else if ( nH == nGreen) + dHue = 120.0 + ( 60.0 * ( nBlue - nRed) / double( nH - nL)) ; + else if ( nH == nBlue) + dHue = 240.0 + ( 60.0 * ( nRed - nGreen) / double( nH - nL)) ; + + // calcolo indice ACI + // scala di grigi -> 250...255 + if ( dSat < 0.1) { + if ( dValue < 0.3) + nColor = 250 ; + else if ( dValue < 0.45) + nColor = 251 ; + else if ( dValue < 0.6) + nColor = 252 ; + else if ( dValue < 0.75) + nColor = 253 ; + else if ( dValue < 0.9) + nColor = 254 ; + else + nColor = 255 ; + return true ; + } + // colori generali -> 10...249 + // prime due cifre sono dHue (angolo) / 1.5, con offset di 10 + // ultima cifra 0,1 = 100% dValue, 2,3 = 80%, 4,5 = 60%, 6,7 = 50%, 8,9 = 30% + // ultima cifra dispari se dSat < 50% altrimenti pari + nColor = 10 + int( dHue / 1.5 + 0.9) ; + nColor = max( 10, min( 249, nColor)) ; + nColor -= ( nColor % 10) ; // per avere l'ultima cifra uguale a 0 + if ( dValue < 0.31) + nColor += 8 ; + else if ( dValue < 0.51) + nColor += 6 ; + else if ( dValue < 0.61) + nColor += 4 ; + else if ( dValue < 0.81) + nColor += 2 ; + else + nColor += 0 ; + if ( dSat < 0.55) + nColor += 1 ; + + return true ; +} + +//---------------------------------------------------------------------------- +string +ExportDxf::UpdateLayerName( const IGdbIterator& iIter, const string& sLay, bool* pbExact) +{ + string sNewLay ; + string sName ; + if ( iIter.GetName( sName)) { + if ( m_bCompoundLayer && sLay != LAY_DEFAULT) + sNewLay = sLay + "_" + sName ; + else + sNewLay = sName ; + if ( pbExact != nullptr) + *pbExact = true ; + } + else { + sNewLay = sLay ; + if ( pbExact != nullptr) + *pbExact = false ; + } + return sNewLay ; +} + diff --git a/ExportDxf.h b/ExportDxf.h new file mode 100644 index 0000000..51b6da1 --- /dev/null +++ b/ExportDxf.h @@ -0,0 +1,75 @@ +//---------------------------------------------------------------------------- +// EgalTech 2014-2014 +//---------------------------------------------------------------------------- +// File : ExportDxf.h Data : 07.08.14 Versione : 1.5h2 +// Contenuto : Dichiarazione della classe ExportDxf. +// +// +// +// Modifiche : 07.08.14 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "/EgtDev/Include/EExExportDxf.h" +#include +#include + +class IGdbIterator ; +class IGeoObj ; +class ICurve ; +class ICurveLine ; +class ICurveArc ; +class Frame3d ; + +//---------------------------------------------------------------------------- +class ExportDxf : public IExportDxf +{ + public : + virtual bool SetOptions( int nFilter, int nFlag) ; + virtual bool Export( IGeomDB* pGDB, int nId, const std::string& sFile) ; + + public : + ExportDxf( void) : m_nFilter( EEXFLT_DEFAULT), m_bCompoundLayer( true), m_bColorByLayer( false) {} + + private : + typedef std::pair LAYDAT ; + typedef std::vector LAYDATVECTOR ; + + private : + bool ExportHeader( IGeomDB* pGDB, int nId) ; + bool ExportTables( IGeomDB* pGDB, int nId) ; + bool WriteLinetypesTable( IGeomDB* pGDB, int nId) ; + bool WriteLayersTable( IGeomDB* pGDB, int nId) ; + bool FindLayers( const IGdbIterator& iIter, const std::string& sLay, LAYDATVECTOR& vLayDat) ; + bool WriteLayer( const std::string& sLay, int nFlag, int nCol, const std::string& sLineType) ; + bool ExportEntities( IGeomDB* pGDB, int nId) ; + bool ExportGdbObject( const IGdbIterator& iIter, const std::string& sLay) ; + bool ExportGdbGroup( const IGdbIterator& iIter, const std::string& sLay) ; + bool ExportPoint( const std::string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) ; + bool ExportVector( const std::string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) ; + bool ExportLine( const std::string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) ; + bool ExportArc( const std::string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) ; + bool ExportCrvBezier( const std::string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) ; + bool ExportCrvCompo( const std::string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) ; + bool ExportSTM( const std::string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame) ; + bool WritePoint( const std::string& sLay, int nCol, const Point3d& ptP, const Vector3d& vtV, const Frame3d& frFrame) ; + bool WriteLine( const std::string& sLay, int nCol, const ICurveLine* pLine, const Frame3d& frFrame) ; + bool WriteCircle( const std::string& sLay, int nCol, const ICurveArc* pArc, const Frame3d& frFrame) ; + bool WriteArc( const std::string& sLay, int nCol, const ICurveArc* pArc, const Frame3d& frFrame) ; + bool WriteCurve3d( const std::string& sLay, int nCol, const ICurve* pCrv, const Frame3d& frFrame) ; + bool TestFilter( int nLev, int nMode, int nStat) ; + bool WriteItem( int nCode, int nVal) ; + bool WriteItem( int nCode, double dVal, int nPrec = 6) ; + bool WriteItem( int nCode, const std::string& sVal) ; + bool ColorToACI( const Color& cCol, int& nColor) ; + std::string UpdateLayerName( const IGdbIterator& iIter, const std::string& sLay, bool* pbExact = nullptr) ; + + private : + int m_nFilter ; + bool m_bCompoundLayer ; + bool m_bColorByLayer ; + std::ofstream m_OutFile ; +} ; diff --git a/ExportStl.cpp b/ExportStl.cpp new file mode 100644 index 0000000..39a1797 --- /dev/null +++ b/ExportStl.cpp @@ -0,0 +1,216 @@ +//---------------------------------------------------------------------------- +// EgalTech 2014-2014 +//---------------------------------------------------------------------------- +// File : ExportStl.cpp Data : 07.08.14 Versione : 1.5h2 +// Contenuto : Implementazione della classe per l'esportazione in formato STL. +// +// +// +// Modifiche : 07.08.14 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "ExportStl.h" +#include "DllMain.h" +#include "/EgtDev/Include/EGkGeomDB.h" +#include "/EgtDev/Include/EGkSurfTriMesh.h" +#include "/EgtDev/Include/EGkGdbIterator.h" +#include "/EgtDev/Include/EgnStringUtils.h" +#include "/EgtDev/Include/EgnStringConverter.h" +#include "/EgtDev/Include/EgtPointerOwner.h" +#include + +using namespace std ; + +//---------------------------------------------------------------------------- +IExportStl* +CreateExportStl( void) +{ + return static_cast ( new(nothrow) ExportStl) ; +} + +//---------------------------------------------------------------------------- +bool +ExportStl::SetOptions( int nFilter) +{ + m_nFilter = nFilter ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportStl::Export( IGeomDB* pGDB, int nId, const string& sFile) +{ + // verifico il DB geometrico + if ( pGDB == nullptr) { + LOG_ERROR( GetEExLogger(), "ExportStl : Error on GeomDB") + return false ; + } + + // verifico l'Id dell'oggetto da esportare + if ( ! pGDB->ExistsObj( nId)) { + LOG_ERROR( GetEExLogger(), "ExportStl : Error on Id") + return false ; + } + + // apro il file di testo in scrittura + ofstream OutFile( stringtoW( sFile), ios::out, _SH_DENYWR) ; + if ( ! OutFile.good()) { + LOG_ERROR( GetEExLogger(), "ExportStl : Error on open file") + return false ; + } + + // creo un iteratore + PtrOwner pIter( CreateGdbIterator( pGDB)) ; + if ( ! ::IsValid( pIter)) + return false ; + pIter->GoTo( nId) ; + // esporto l'oggetto e i suoi eventuali figli + bool bOk = ExportObject( *pIter, OutFile) ; + + // chiudo il file + if ( ! OutFile.good() || ! OutFile.is_open()) + bOk = false ; + if ( OutFile.is_open()) + OutFile.close() ; + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +ExportStl::ExportObject( const IGdbIterator& iIter, ofstream& OutFile) +{ + switch ( iIter.GetGdbType()) { + case GDB_TY_GEO : + { + // recupero l'oggetto geometrico + const IGeoObj* pGeoObj =(const_cast(&iIter))->GetGeoObj() ; + if ( pGeoObj == nullptr) + return true ; + // recupero il riferimento globale dell'oggetto + Frame3d frFrame ; + if ( ! iIter.GetGlobFrame( frFrame)) + return false ; + // recupero il livello dell'oggetto + int nLev = GDB_LV_USER ; + iIter.GetCalcLevel( nLev) ; + // recupero il modo dell'oggetto + int nMode = GDB_MD_STD ; + iIter.GetCalcMode( nMode) ; + // recupero lo stato dell'oggetto + int nStat = GDB_ST_ON ; + iIter.GetCalcStatus( nStat) ; + // se il filtro lo abilita + if ( TestFilter( nLev, nMode, nStat)) { + // recupero eventuale nome + string sName ; + if ( ! iIter.GetName( sName)) + sName = ToString( iIter.GetId()) ; + // emetto l'oggetto + switch ( pGeoObj->GetType()) { + case SRF_TRIMESH : + if ( ! ExportSTM( sName, pGeoObj, frFrame, OutFile)) + return false ; + break ; + default : + break ; + } + } + } + return true ; + case GDB_TY_GROUP : + // esploro il gruppo + return ScanGroup( iIter, OutFile) ; + default : + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +ExportStl::TestFilter( int nLev, int nMode, int nStat) +{ + if ( ( nLev == GDB_LV_USER && ( m_nFilter & EEXFLT_LEVUSER) == 0) || + ( nLev == GDB_LV_SYSTEM && ( m_nFilter & EEXFLT_LEVSYSTEM) == 0) || + ( nLev == GDB_LV_TEMP && ( m_nFilter & EEXFLT_LEVTEMP) == 0)) + return false ; + if ( ( nMode == GDB_MD_STD && ( m_nFilter & EEXFLT_MODESTD) == 0) || + ( nMode == GDB_MD_LOCKED && ( m_nFilter & EEXFLT_MODELOCKED) == 0) || + ( nMode == GDB_MD_HIDDEN && ( m_nFilter & EEXFLT_MODEHIDDEN) == 0)) + return false ; + if ( ( nStat == GDB_ST_OFF && ( m_nFilter & EEXFLT_STAOFF) == 0) || + ( nStat == GDB_ST_ON && ( m_nFilter & EEXFLT_STAON) == 0) || + ( nStat == GDB_ST_SEL && ( m_nFilter & EEXFLT_STASEL) == 0)) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportStl::ExportSTM( const string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame, + ofstream& OutFile) +{ + // verifico oggetto + const ISurfTriMesh* pSTM = GetSurfTriMesh( pGeoObj) ; + if ( pSTM == nullptr) + return false ; + + try { + // inizio oggetto + OutFile << "solid " << sName << endl ; + + // ciclo sui triangoli della trimesh + Triangle3d Tria ; + int nId = pSTM->GetFirstTriangle( Tria) ; + while ( nId != SVT_NULL) { + // lo porto in coordinate globali + Tria.ToGlob( frFrame) ; + // emetto il triangolo + OutFile << " facet normal " << ToString( Tria.GetN().x) << + " " << ToString( Tria.GetN().y) << + " " << ToString( Tria.GetN().z) << endl ; + OutFile << " outer loop" << endl ; + for ( int i = 0 ; i < 3 ; ++ i) { + OutFile << " vertex " << ToString( Tria.GetP( i).x) << + " " << ToString( Tria.GetP( i).y) << + " " << ToString( Tria.GetP( i).z) << endl ; + } + OutFile << " endloop" << endl ; + OutFile << " endfacet" << endl ; + // passo al successivo + nId = pSTM->GetNextTriangle( nId, Tria) ; + } + + // termino oggetto + OutFile << "endsolid" << endl ; + } + catch( ...) + { return false ; } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +ExportStl::ScanGroup( const IGdbIterator& iIter, ofstream& OutFile) +{ + // creo un iteratore + PtrOwner pIter( CreateGdbIterator( iIter.GetGDB())) ; + if ( ! ::IsValid( pIter)) + return false ; + // scandisco il gruppo + bool bOk = true ; + for ( bool bNext = pIter->GoToFirstInGroup( iIter) ; + bNext ; + bNext = pIter->GoToNext()) { + if ( ! ExportObject( *pIter, OutFile)) + bOk = false ; + } + + return bOk ; +} + diff --git a/ExportStl.h b/ExportStl.h new file mode 100644 index 0000000..5422973 --- /dev/null +++ b/ExportStl.h @@ -0,0 +1,40 @@ +//---------------------------------------------------------------------------- +// EgalTech 2014-2014 +//---------------------------------------------------------------------------- +// File : ExportStl.h Data : 07.08.14 Versione : 1.5h2 +// Contenuto : Dichiarazione della classe ExportStl. +// +// +// +// Modifiche : 07.08.14 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "/EgtDev/Include/EExExportStl.h" + +class IGdbIterator ; +class IGeoObj ; +class Frame3d ; + +//---------------------------------------------------------------------------- +class ExportStl : public IExportStl +{ + public : + virtual bool SetOptions( int nFilter) ; + virtual bool Export( IGeomDB* pGDB, int nId, const std::string& sFile) ; + + public : + ExportStl( void) : m_nFilter( EEXFLT_DEFAULT) {} + + private : + bool ExportObject( const IGdbIterator& iIter, std::ofstream& OutFile) ; + bool ScanGroup( const IGdbIterator& iIter, std::ofstream& OutFile) ; + bool TestFilter( int nLev, int nMode, int nStat) ; + bool ExportSTM( const std::string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame, std::ofstream& OutFile) ; + + private : + int m_nFilter ; +} ; diff --git a/ImportDxfEnts.cpp b/ImportDxfEnts.cpp index 77e7aa7..32dd0e7 100644 --- a/ImportDxfEnts.cpp +++ b/ImportDxfEnts.cpp @@ -20,6 +20,7 @@ #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EgkGeoPoint3d.h" +#include "/EgtDev/Include/EgkGeoVector3d.h" #include "/EgtDev/Include/EgkCurveLine.h" #include "/EgtDev/Include/EgkCurveArc.h" #include "/EgtDev/Include/EgkCurveComposite.h" @@ -1272,6 +1273,7 @@ ImportDxf::ReadPoint( bool& bFileEnd) { Point3d ptP ; Vector3d vtExtr( 0, 0, 1) ; + double dThick = 0 ; string sLayer ; int nSpace = ENT_MODELSPACE ; int nColor = COL_BYLAYER ; @@ -1300,6 +1302,9 @@ ImportDxf::ReadPoint( bool& bFileEnd) case 30 : FromString( m_sCurrItem, ptP.z) ; break ; + case 39 : + FromString( m_sCurrItem, dThick) ; + break ; case 60 : FromString( m_sCurrItem, nSpace) ; break ; @@ -1328,22 +1333,39 @@ ImportDxf::ReadPoint( bool& bFileEnd) ValidateName( sLayer) ; // aggiusto per il fattore di scala ptP *= m_dScaleFactor ; + dThick *= m_dScaleFactor ; // gestisco il riferimento del gruppo di inserimento if ( ! BlockReading()) ptP.ToLoc( m_frGroup) ; - // inserisco il punto nel DB geometrico - // creo il punto - PtrOwner pGeoPnt( CreateGeoPoint3d()) ; - if ( ! IsValid( pGeoPnt)) - return false ; - // setto il punto - if ( ! pGeoPnt->Set( ptP)) - return false ; - // inserisco il punto nel DB - int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pGeoPnt)) ; + // inserisco l'entità nel DB geometrico + PtrOwner pGeoObj ; ; + if ( fabs( dThick) < EPS_SMALL) { + // creo il punto + PtrOwner pGeoPnt( CreateGeoPoint3d()) ; + if ( ! IsValid( pGeoPnt)) + return false ; + // setto il punto + if ( ! pGeoPnt->Set( ptP)) + return false ; + // lo passo all'oggetto geometrico generico + pGeoObj.Set( Release( pGeoPnt)) ; + } + else { + // creo il vettore con punto base + PtrOwner pGeoVect( CreateGeoVector3d()) ; + if ( ! IsValid( pGeoVect)) + return false ; + // setto il punto + if ( ! pGeoVect->Set( dThick * vtExtr, ptP)) + return false ; + // lo passo all'oggetto geometrico generico + pGeoObj.Set( Release( pGeoVect)) ; + } + // inserisco l'entità nel DB + int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), Release( pGeoObj)) ; if ( nId == GDB_ID_NULL) return false ; - // eventuale assegnazione del colore + // eventuale assegnazione del colore if ( ! SetColor( nId, nColor, sLayer)) return false ; return true ; @@ -1453,7 +1475,11 @@ ImportDxf::CompletePolyLine( const string& sLayer, int nColor, int nFlag, bool b if ( sEntName == "VERTEX") { if ( ! ReadPolyLineVertex( VertTmp, bFileEnd)) bOkLoc = false ; - if ( ! bIs3d) + // se polilinea 3d non sono ammessi archi (bulge = 0) + if ( bIs3d) + VertTmp.first = 0 ; + // altrimenti polilinea 2d quindi z = 0 + else VertTmp.second.z = 0 ; vVert.push_back( VertTmp) ; nNumVert ++ ; @@ -1481,6 +1507,9 @@ ImportDxf::CompletePolyLine( const string& sLayer, int nColor, int nFlag, bool b // se entità da saltare, esco if ( ! bToSave) return true ; + // se un solo vertice, esco + if ( nNumVert <= 1) + return true ; // Se chiusa, aggiungo un punto uguale al primo in coda if ( nFlag & 1) { vVert.push_back( vVert[0]) ; @@ -2170,7 +2199,7 @@ ImportDxf::ReadSpline( bool& bFileEnd) for ( int i = 0 ; i < int( vIntPnt.size()) ; ++ i) crvByInterp.AddPoint( vIntPnt[i]) ; crvByInterp.End() ; - PtrOwner pCrv( crvByInterp.GetCurve( CurveByInterp::BESSEL, CurveByInterp::CUBIC_BEZIER)) ; + PtrOwner pCrv( crvByInterp.GetCurve( CurveByInterp::BESSEL, CurveByInterp::CUBIC_BEZIERS)) ; if ( ! ::IsValid( pCrv)) return false ; // Inserisco la curva nel DB @@ -2208,8 +2237,8 @@ ImportDxf::ReadSpline( bool& bFileEnd) if ( ! NurbsCurveCanonicalize( cnData)) return false ; // creo la curva equivalente alla Nurbs - ICurve* pCrv ; - if ( ! NurbsToBezierCurve( cnData, pCrv)) + ICurve* pCrv = NurbsToBezierCurve( cnData) ; + if ( pCrv == nullptr) return false ; // Inserisco la curva composita nel DB int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetGroupId( sLayer), pCrv) ; diff --git a/ImportDxfHeader.cpp b/ImportDxfHeader.cpp index 3b200f4..f4e5013 100644 --- a/ImportDxfHeader.cpp +++ b/ImportDxfHeader.cpp @@ -54,6 +54,7 @@ ImportDxf::ReadHeader( bool& bFileEnd) case 3 : if ( bCodePage) { string sCodePage = m_sCurrItem ; + ToUpper( sCodePage) ; ReplaceString( sCodePage, "ANSI_", "") ; ReplaceString( sCodePage, "DOS", "") ; int nVal ;