Files
Dario Sassi f54f1f8969 EgtExchange 2.6l1 :
- aggiunta importazione formato OFF (Object File Format).
2024-11-29 18:18:28 +01:00

2048 lines
66 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : ExportDxf.cpp Data : 07.08.14 Versione : 1.5h2
// Contenuto : Implementazione della classe per l'esportazione in formato DXF.
// Versione ACAD 1009 quindi DXF R12 (handles disabilitati).
//
//
// 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/EExDllMain.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/EGkSurfFlatRegion.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkExtText.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EGnFileUtils.h"
#include "/EgtDev/Include/EgtStringConverter.h"
#include "/EgtDev/Include/EgtStringDecoder.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
IExportDxf*
CreateExportDxf( void)
{
// verifico la chiave e le opzioni
if ( ! VerifyKey( KEYOPT_EEX_EXPBASE))
return nullptr ;
// creo l'oggetto
return static_cast<IExportDxf*> ( new(nothrow) ExportDxf) ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::SetOptions( int nFilter, int nFlag)
{
m_nFilter = nFilter ;
CalcGroupFilter() ;
m_bCompoundLayer = (( nFlag & EEXFLAG_COMP_LAYER) != 0) ;
m_bColorByLayer = (( nFlag & EEXFLAG_COL_BY_LAYER) != 0) ;
m_bAdvancedNames = (( nFlag & EEXFLAG_ADV_NAMES) != 0) ;
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_Writer.Close() ;
if ( ! m_Writer.Init( sFile)) {
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 blocchi
if ( ! ExportBlocks( 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_Writer.Close())
bOk = false ;
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 ;
// altri dati
if ( ! WriteItem( 9, "$DWGCODEPAGE") ||
! WriteItem( 3, "ansi_1252") ||
! WriteItem( 9, "$INSBASE") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 30, "0.0"))
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 ;
// altri dati
if ( ! WriteItem( 9, "$LIMMIN") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 9, "$LIMMAX") ||
! WriteItem( 10, "12.0") ||
! WriteItem( 20, "9.0") ||
! WriteItem( 9, "$ORTHOMODE") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$REGENMODE") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$FILLMODE") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$QTEXTMODE") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$MIRRTEXT") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$DRAGMODE") ||
! WriteItem( 70, "2") ||
! WriteItem( 9, "$LTSCALE") ||
! WriteItem( 40, "1.0") ||
! WriteItem( 9, "$OSMODE") ||
! WriteItem( 70, "37") ||
! WriteItem( 9, "$ATTMODE") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$TEXTSIZE") ||
! WriteItem( 40, "10.0") ||
! WriteItem( 9, "$TRACEWID") ||
! WriteItem( 40, "0.05") ||
! WriteItem( 9, "$TEXTSTYLE") ||
! WriteItem( 7, "STANDARD") ||
! WriteItem( 9, "$CLAYER") ||
! WriteItem( 8, "0") ||
! WriteItem( 9, "$CELTYPE") ||
! WriteItem( 6, "BYBLOCK") ||
! WriteItem( 9, "$CECOLOR") ||
! WriteItem( 62, "256") ||
! WriteItem( 9, "$DIMSCALE") ||
! WriteItem( 40, "1.0") ||
! WriteItem( 9, "$DIMASZ") ||
! WriteItem( 40, "0.18") ||
! WriteItem( 9, "$DIMEXO") ||
! WriteItem( 40, "0.0625") ||
! WriteItem( 9, "$DIMDLI") ||
! WriteItem( 40, "0.38") ||
! WriteItem( 9, "$DIMRND") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$DIMDLE") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$DIMEXE") ||
! WriteItem( 40, "0.18") ||
! WriteItem( 9, "$DIMTP") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$DIMTM") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$DIMTXT") ||
! WriteItem( 40, "0.18") ||
! WriteItem( 9, "$DIMCEN") ||
! WriteItem( 40, "0.09") ||
! WriteItem( 9, "$DIMTSZ") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$DIMTOL") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMLIM") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMTIH") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$DIMTOH") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$DIMSE1") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMSE2") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMTAD") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMZIN") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMBLK") ||
! WriteItem( 1, "") ||
! WriteItem( 9, "$DIMASO") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$DIMSHO") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$DIMPOST") ||
! WriteItem( 1, "") ||
! WriteItem( 9, "$DIMAPOST") ||
! WriteItem( 1, "") ||
! WriteItem( 9, "$DIMALT") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMALTD") ||
! WriteItem( 70, "2") ||
! WriteItem( 9, "$DIMALTF") ||
! WriteItem( 40, "25.4") ||
! WriteItem( 9, "$DIMLFAC") ||
! WriteItem( 40, "1.0") ||
! WriteItem( 9, "$DIMTOFL") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMTVP") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$DIMTIX") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMSOXD") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMSAH") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMBLK1") ||
! WriteItem( 1, "") ||
! WriteItem( 9, "$DIMBLK2") ||
! WriteItem( 1, "") ||
! WriteItem( 9, "$DIMSTYLE") ||
! WriteItem( 2, "STANDARD") ||
! WriteItem( 9, "$DIMCLRD") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMCLRE") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMCLRT") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$DIMTFAC") ||
! WriteItem( 40, "1.0") ||
! WriteItem( 9, "$DIMGAP") ||
! WriteItem( 40, "0.09") ||
! WriteItem( 9, "$LUNITS") ||
! WriteItem( 70, "2") ||
! WriteItem( 9, "$LUPREC") ||
! WriteItem( 70, "4") ||
! WriteItem( 9, "$SKETCHINC") ||
! WriteItem( 40, "0.1") ||
! WriteItem( 9, "$FILLETRAD") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$AUNITS") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$AUPREC") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$MENU") ||
! WriteItem( 1, ".") ||
! WriteItem( 9, "$ELEVATION") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$PELEVATION") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$THICKNESS") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$LIMCHECK") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$CHAMFERA") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$CHAMFERB") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$SKPOLY") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$TDCREATE") ||
! WriteItem( 40, "2459110.411952581") ||
! WriteItem( 9, "$TDUPDATE") ||
! WriteItem( 40, "2459110.411952651") ||
! WriteItem( 9, "$TDINDWG") ||
! WriteItem( 40, "0.0000000116") ||
! WriteItem( 9, "$TDUSRTIMER") ||
! WriteItem( 40, "0.0000000116") ||
! WriteItem( 9, "$USRTIMER") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$ANGBASE") ||
! WriteItem( 50, "0.0") ||
! WriteItem( 9, "$ANGDIR") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$PDMODE") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$PDSIZE") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$PLINEWID") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$COORDS") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$SPLFRAME") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$SPLINETYPE") ||
! WriteItem( 70, "6") ||
! WriteItem( 9, "$SPLINESEGS") ||
! WriteItem( 70, "8") ||
! WriteItem( 9, "$ATTDIA") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$ATTREQ") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$HANDLING") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$HANDSEED") ||
! WriteItem( 5, "0") ||
! WriteItem( 9, "$SURFTAB1") ||
! WriteItem( 70, "6") ||
! WriteItem( 9, "$SURFTAB2") ||
! WriteItem( 70, "6") ||
! WriteItem( 9, "$SURFTYPE") ||
! WriteItem( 70, "6") ||
! WriteItem( 9, "$SURFU") ||
! WriteItem( 70, "6") ||
! WriteItem( 9, "$SURFV") ||
! WriteItem( 70, "6") ||
! WriteItem( 9, "$UCSNAME") ||
! WriteItem( 2, "") ||
! WriteItem( 9, "$UCSORG") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 30, "0.0") ||
! WriteItem( 9, "$UCSXDIR") ||
! WriteItem( 10, "1.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 30, "0.0") ||
! WriteItem( 9, "$UCSYDIR") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "1.0") ||
! WriteItem( 30, "0.0") ||
! WriteItem( 9, "$PUCSNAME") ||
! WriteItem( 2, "") ||
! WriteItem( 9, "$PUCSORG") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 30, "0.0") ||
! WriteItem( 9, "$PUCSXDIR") ||
! WriteItem( 10, "1.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 30, "0.0") ||
! WriteItem( 9, "$PUCSYDIR") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "1.0") ||
! WriteItem( 30, "0.0") ||
! WriteItem( 9, "$USERI1") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$USERI2") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$USERI3") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$USERI4") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$USERI5") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$USERR1") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$USERR2") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$USERR3") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$USERR4") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$USERR5") ||
! WriteItem( 40, "0.0") ||
! WriteItem( 9, "$WORLDVIEW") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$SHADEDGE") ||
! WriteItem( 70, "3") ||
! WriteItem( 9, "$SHADEDIF") ||
! WriteItem( 70, "70") ||
! WriteItem( 9, "$TILEMODE") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$MAXACTVP") ||
! WriteItem( 70, "64") ||
! WriteItem( 9, "$PLIMCHECK") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$PEXTMIN") ||
! WriteItem( 10, "1.000000000000000E+20") ||
! WriteItem( 20, "1.000000000000000E+20") ||
! WriteItem( 30, "1.000000000000000E+20") ||
! WriteItem( 9, "$PEXTMAX") ||
! WriteItem( 10, "-1.000000000000000E+20") ||
! WriteItem( 20, "-1.000000000000000E+20") ||
! WriteItem( 30, "-1.000000000000000E+20") ||
! WriteItem( 9, "$PLIMMIN") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 9, "$PLIMMAX") ||
! WriteItem( 10, "12.0") ||
! WriteItem( 20, "9.0") ||
! WriteItem( 9, "$UNITMODE") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$VISRETAIN") ||
! WriteItem( 70, "1") ||
! WriteItem( 9, "$PLINEGEN") ||
! WriteItem( 70, "0") ||
! WriteItem( 9, "$PSLTSCALE") ||
! WriteItem( 70, "1")
)
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 VPORT
if ( ! WriteVPortTable( pGDB, nId))
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 ;
// scrittura tavola per stili di testo
if ( ! WriteStylesTable( pGDB, nId))
return false ;
// scrittura tavole varie
if ( ! WriteOtherTables( pGDB, nId))
return false ;
// terminazione sezione tables
if ( ! WriteItem( 0, "ENDSEC"))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteVPortTable( IGeomDB* pGDB, int nId)
{
// scrittura intestazione della tavola
if ( ! WriteItem( 0, "TABLE") ||
! WriteItem( 2, "VPORT"))
return false ;
// dati
if ( ! WriteItem( 70, "1") ||
! WriteItem( 0, "VPORT") ||
! WriteItem( 2, "*ACTIVE") ||
! WriteItem( 70, "0") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 11, "1.0") ||
! WriteItem( 21, "1.0") ||
! WriteItem( 12, "10.42990654205607") ||
! WriteItem( 22, "4.5") ||
! WriteItem( 13, "0.0") ||
! WriteItem( 23, "0.0") ||
! WriteItem( 14, "0.5") ||
! WriteItem( 24, "0.5") ||
! WriteItem( 15, "0.5") ||
! WriteItem( 25, "0.5") ||
! WriteItem( 16, "0.0") ||
! WriteItem( 26, "0.0") ||
! WriteItem( 36, "1.0") ||
! WriteItem( 17, "0.0") ||
! WriteItem( 27, "0.0") ||
! WriteItem( 37, "0.0") ||
! WriteItem( 40, "9.0") ||
! WriteItem( 41, "1.972972972850329") ||
! WriteItem( 42, "50.0") ||
! WriteItem( 43, "0.0") ||
! WriteItem( 44, "0.0") ||
! WriteItem( 50, "0.0") ||
! WriteItem( 51, "0.0") ||
! WriteItem( 71, "0") ||
! WriteItem( 72, "100") ||
! WriteItem( 73, "1") ||
! WriteItem( 74, "3") ||
! WriteItem( 75, "0") ||
! WriteItem( 76, "0") ||
! WriteItem( 77, "0") ||
! WriteItem( 78, "0"))
return false ;
// scrittura terminazione della tavola
if ( ! WriteItem( 0, "ENDTAB"))
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<IGdbIterator> pIter( CreateGdbIterator( pGDB)) ;
if ( IsNull( 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 ;
// 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 non lo abilita, esco subito
if ( ! TestFilter( nLev, nMode, nStat, true))
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.emplace_back( sNewLay, nCol) ;
// scandisco il gruppo alla ricerca di sottogruppi
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( iIter.GetGDB())) ;
if ( IsNull( 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::WriteStylesTable( IGeomDB* pGDB, int nId)
{
// ciclo di ricerca dei testi
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( pGDB)) ;
if ( IsNull( pIter))
return false ;
pIter->GoTo( nId) ;
// eseguo la ricerca
STRVECTOR vFontName ;
if ( ! FindTextStyles( *pIter, vFontName))
return false ;
// scrittura intestazione della tavola
if ( ! WriteItem( 0, "TABLE") ||
! WriteItem( 2, "STYLE"))
return false ;
// numero di stili di testo
//int nFontNbr = int( vFontName.size()) ;
//if ( ! WriteItem( 70, 1 + nFontNbr))
if ( ! WriteItem( 70, 1))
return false ;
// scrittura stile di testo standard
if ( ! WriteStyle( "STANDARD", "isocp.shx"))
return false ;
// scrittura degli stili di testo
//for ( int i = 0 ; i < nFontNbr ; ++i) {
// if ( ! WriteStyle( FontNameToStyle( vFontName[i]), AdjustFontName( vFontName[i])))
// return false ;
//}
// scrittura terminazione della tavola
if ( ! WriteItem( 0, "ENDTAB"))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::FindTextStyles( const IGdbIterator& iIter, STRVECTOR& vFontName)
{
// se una entit geometrica
if ( iIter.GetGdbType() == GDB_TY_GEO) {
// se un testo
if ( const IExtText* pTXT = GetExtText( iIter.GetGeoObj())) {
// se font non presente, lo aggiungo al vettore dei font
bool bFound = false ;
for ( int i = 0 ; ! bFound && i < int( vFontName.size()) ; ++ i) {
string s1 = vFontName[i] ;
string s2 = pTXT->GetFont() ;
if ( ToUpper( s1) == ToUpper( s2))
bFound = true ;
}
if ( ! bFound)
vFontName.push_back( pTXT->GetFont()) ;
}
return true ;
}
// se un gruppo, scandisco i suoi figli
else if ( iIter.GetGdbType() == GDB_TY_GROUP) {
// scandisco il gruppo
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( iIter.GetGDB())) ;
if ( IsNull( pIter))
return false ;
bool bOk = true ;
for ( bool bNext = pIter->GoToFirstInGroup( iIter) ;
bNext ;
bNext = pIter->GoToNext()) {
if ( ! FindTextStyles( *pIter, vFontName))
bOk = false ;
}
return bOk ;
}
else
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteStyle( const string& sStyle, const string& sFont)
{
// intestazione layer
if ( ! WriteItem( 0, "STYLE"))
return false ;
// nome stile
if ( ! WriteItem( 2, sStyle))
return false ;
// flag
if ( ! WriteItem( 70, 0))
return false ;
// altezza testo
if ( ! WriteItem( 40, 0))
return false ;
// rapporto altezza/larghezza
if ( ! WriteItem( 41, 1))
return false ;
// angolo obliquo
if ( ! WriteItem( 50, 0))
return false ;
// flag di generazione
if ( ! WriteItem( 71, 0))
return false ;
// ultima altezza usata
if ( ! WriteItem( 42, 10))
return false ;
// nome font
if ( ! WriteItem( 3, sFont))
return false ;
// big font file name
if ( ! WriteItem( 4, ""))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteOtherTables( IGeomDB* pGDB, int nId)
{
// tavola VIEW
if ( ! WriteItem( 0, "TABLE") ||
! WriteItem( 2, "VIEW") ||
! WriteItem( 70, "0") ||
! WriteItem( 0, "ENDTAB"))
return false ;
// tavola UCS
if ( ! WriteItem( 0, "TABLE") ||
! WriteItem( 2, "UCS") ||
! WriteItem( 70, "0") ||
! WriteItem( 0, "ENDTAB"))
return false ;
// tavola APPID/ACAD
if ( ! WriteItem( 0, "TABLE") ||
! WriteItem( 2, "APPID") ||
! WriteItem( 70, "1") ||
! WriteItem( 0, "APPID") ||
! WriteItem( 2, "ACAD") ||
! WriteItem( 70, "0") ||
! WriteItem( 0, "ENDTAB"))
return false ;
// tavola DIMSTYLE
if ( ! WriteItem( 0, "TABLE") ||
! WriteItem( 2, "DIMSTYLE") ||
! WriteItem( 70, "1") ||
! WriteItem( 0, "DIMSTYLE") ||
! WriteItem( 2, "STANDARD") ||
! WriteItem( 70, "0") ||
! WriteItem( 3, "") ||
! WriteItem( 4, "") ||
! WriteItem( 5, "") ||
! WriteItem( 6, "") ||
! WriteItem( 7, "") ||
! WriteItem( 40, "1.0") ||
! WriteItem( 41, "0.18") ||
! WriteItem( 42, "0.0625") ||
! WriteItem( 43, "0.38") ||
! WriteItem( 44, "0.18") ||
! WriteItem( 45, "0.0") ||
! WriteItem( 46, "0.0") ||
! WriteItem( 47, "0.0") ||
! WriteItem( 48, "0.0") ||
! WriteItem( 140, "0.18") ||
! WriteItem( 141, "0.09") ||
! WriteItem( 142, "0.0") ||
! WriteItem( 143, "25.4") ||
! WriteItem( 144, "1.0") ||
! WriteItem( 145, "0.0") ||
! WriteItem( 146, "1.0") ||
! WriteItem( 147, "0.09") ||
! WriteItem( 71, "0") ||
! WriteItem( 72, "0") ||
! WriteItem( 73, "1") ||
! WriteItem( 74, "1") ||
! WriteItem( 75, "0") ||
! WriteItem( 76, "0") ||
! WriteItem( 77, "0") ||
! WriteItem( 78, "0") ||
! WriteItem( 170, "0") ||
! WriteItem( 171, "2") ||
! WriteItem( 172, "0") ||
! WriteItem( 173, "0") ||
! WriteItem( 174, "0") ||
! WriteItem( 175, "0") ||
! WriteItem( 176, "0") ||
! WriteItem( 177, "0") ||
! WriteItem( 178, "0") ||
! WriteItem( 0, "ENDTAB"))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::ExportBlocks( IGeomDB* pGDB, int nId)
{
// intestazione sezione blocks
if ( ! WriteItem( 0, "SECTION") ||
! WriteItem( 2, "BLOCKS"))
return false ;
// blocco ModelSpace
if ( ! WriteItem( 0, "BLOCK") ||
! WriteItem( 8, "0") ||
! WriteItem( 2, "$MODEL_SPACE") ||
! WriteItem( 70, "0") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 30, "0.0") ||
! WriteItem( 3, "$MODEL_SPACE") ||
! WriteItem( 1, "") ||
! WriteItem( 0, "ENDBLK"))
return false ;
// blocco PaperSpace
if ( ! WriteItem( 0, "BLOCK") ||
! WriteItem( 67, "1") ||
! WriteItem( 8, "0") ||
! WriteItem( 2, "$PAPER_SPACE") ||
! WriteItem( 70, "0") ||
! WriteItem( 10, "0.0") ||
! WriteItem( 20, "0.0") ||
! WriteItem( 30, "0.0") ||
! WriteItem( 3, "$PAPER_SPACE") ||
! WriteItem( 1, "") ||
! WriteItem( 0, "ENDBLK"))
return false ;
// terminazione sezione blocks
if ( ! WriteItem( 0, "ENDSEC"))
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<IGdbIterator> pIter( CreateGdbIterator( pGDB)) ;
if ( IsNull( 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 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) ;
// recupero il tipo dell'oggetto
int nGdbType = iIter.GetGdbType() ;
// se il filtro lo abilita
if ( TestFilter( nLev, nMode, nStat, nGdbType == GDB_TY_GROUP)) {
// se gruppo di oggetti
if ( nGdbType == GDB_TY_GROUP) {
// esporto il gruppo
return ExportGdbGroup( iIter, sLay) ;
}
// se oggetto geometrico
else if ( nGdbType == GDB_TY_GEO) {
// recupero l'oggetto geometrico
const IGeoObj* pGeoObj = iIter.GetGeoObj() ;
if ( pGeoObj == nullptr)
return true ;
// recupero il riferimento globale dell'oggetto
Frame3d frFrame ;
if ( ! iIter.GetGlobFrame( frFrame))
return false ;
// 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_BEZIER :
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 ;
case SRF_FLATRGN :
if ( ! ExportSFR( sLay, nCol, pGeoObj, frFrame))
return false ;
break ;
case EXT_TEXT :
if ( ! ExportText( sLay, nCol, pGeoObj, frFrame))
return false ;
break ;
}
return true ;
}
else
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::ExportGdbGroup( const IGdbIterator& iIter, const string& sLay)
{
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( iIter.GetGDB())) ;
if ( IsNull( 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 o con estrusione non parallela a N
if ( ! pArc->IsPlane()) {
// 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 ;
// verifico se piana
Plane3d plPlane ;
if ( pCBez->IsFlat( plPlane)) {
Frame3d frPlane ;
frPlane.Set( ( ORIG + plPlane.GetDist() * plPlane.GetVersN()), plPlane.GetVersN()) ;
return WriteCurve2d( sLay, nCol, pCBez, frPlane, frFrame) ;
}
// 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 ;
// verifico se piana
Plane3d plPlane ;
if ( pCC->IsFlat( plPlane)) {
Frame3d frPlane ;
frPlane.Set( ( ORIG + plPlane.GetDist() * plPlane.GetVersN()), plPlane.GetVersN()) ;
return WriteCurve2d( sLay, nCol, pCC, frPlane, frFrame) ;
}
// altrimenti esporto come polilinea 3d
return WriteCurve3d( sLay, nCol, pCC, frFrame) ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::ExportSFR( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// deve essere una superficie regione piatta
const ISurfFlatRegion* pSFR = GetSurfFlatRegion( pGeoObj) ;
if ( pSFR == nullptr)
return false ;
// ricavo la trimesh equivalente
const ISurfTriMesh* pStm = pSFR->GetAuxSurf() ;
return ExportSTM( sLay, nCol, pStm, 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 ;
// posso esportare come unica polymesh solo se il numero dei vertici e dei triangoli inferiore a 32767
if ( pSTM->GetVertexCount() < SHRT_MAX && pSTM->GetTriangleCount() < SHRT_MAX) {
// 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->GetVertexCount()))
return false ;
// numero di facce
if ( ! WriteItem( 72, pSTM->GetTriangleCount()))
return false ;
// ciclo sui vertici
Point3d ptP ;
for ( int nId = pSTM->GetFirstVertex( ptP) ;
nId != SVT_NULL ;
nId = pSTM->GetNextVertex( nId, ptP)) {
ptP.ToGlob( frFrame) ;
// entit vertice
if ( ! WriteItem( 0, "VERTEX"))
return false ;
// layer
if ( ! WriteItem( 8, sLay))
return false ;
// punto corrente
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 ;
}
// altrimenti devo esportare come insieme di facce triangolari
else {
// ciclo sui triangoli
Triangle3d Tria ;
for ( int nId = pSTM->GetFirstTriangle( Tria) ;
nId != SVT_NULL ;
nId = pSTM->GetNextTriangle( nId, Tria)) {
Tria.ToGlob( frFrame) ;
// entit 3dface
if ( ! WriteItem( 0, "3DFACE"))
return false ;
// layer
if ( ! WriteItem( 8, sLay))
return false ;
// colore (unico colore riconosciuto)
if ( ! WriteItem( 62, nCol))
return false ;
// primo vertice
if ( ! WriteItem( 10, Tria.GetP(0).x) ||
! WriteItem( 20, Tria.GetP(0).y) ||
! WriteItem( 30, Tria.GetP(0).z))
return false ;
// secondo vertice
if ( ! WriteItem( 11, Tria.GetP(1).x) ||
! WriteItem( 21, Tria.GetP(1).y) ||
! WriteItem( 31, Tria.GetP(1).z))
return false ;
// terzo vertice
if ( ! WriteItem( 12, Tria.GetP(2).x) ||
! WriteItem( 22, Tria.GetP(2).y) ||
! WriteItem( 32, Tria.GetP(2).z))
return false ;
// quarto vertice (ripete il terzo)
if ( ! WriteItem( 13, Tria.GetP(2).x) ||
! WriteItem( 23, Tria.GetP(2).y) ||
! WriteItem( 33, Tria.GetP(2).z))
return false ;
// flag (default)
if ( ! WriteItem( 70, 0))
return false ;
}
return true ;
}
}
//----------------------------------------------------------------------------
bool
ExportDxf::ExportText( const string& sLay, int nCol, const IGeoObj* pGeoObj, const Frame3d& frFrame)
{
// deve essere un testo
const IExtText* pTXT = GetExtText( pGeoObj) ;
if ( pTXT == nullptr)
return false ;
// calcolo riferimento OCS
Vector3d vtN = pTXT->GetNormVersor() ;
vtN.ToGlob( frFrame) ;
Frame3d frOCS ;
frOCS.Set( ORIG, vtN) ;
// divido il testo in testi monolinea
IEXTTEXTPVECTOR vTxt ;
pTXT->SplitOnLineBreak( vTxt) ;
// ciclo sui diversi testi semplici
bool bOk = true ;
for ( int i = 0 ; i < int( vTxt.size()) ; ++ i) {
// identificativo entit
if ( ! WriteItem( 0, "TEXT"))
return false ;
// layer
if ( ! WriteItem( 8, sLay))
return false ;
// colore
if ( ! WriteItem( 62, nCol))
return false ;
// punto di inserimento in OCS
Point3d ptP = vTxt[i]->GetPoint() ;
ptP.LocToLoc( frFrame, frOCS) ;
if ( ! WriteItem( 10, ptP.x) ||
! WriteItem( 20, ptP.y) ||
! WriteItem( 30, ptP.z))
return false ;
// altezza
if ( ! WriteItem( 40, vTxt[i]->GetHeight()))
return false ;
// stringa di testo
string sText = vTxt[i]->GetText() ;
if ( ! AdjustText( sText))
return false ;
if ( ! WriteItem( 1, sText))
return false ;
// angolo di rotazione
Vector3d vtDir = vTxt[i]->GetDirVersor() ;
vtDir.LocToLoc( frFrame, frOCS) ;
double dDirDeg ;
vtDir.ToSpherical( nullptr, nullptr, &dDirDeg) ;
if ( ! WriteItem( 50, dDirDeg))
return false ;
// rapporto altezza/larghezza
if ( ! WriteItem( 41, vTxt[i]->GetRatio()))
return false ;
// stile
if ( ! WriteItem( 7, FontNameToStyle( vTxt[i]->GetFont())))
return false ;
// vettore estrusione
if ( ! WriteItem( 210, vtN.x) ||
! WriteItem( 220, vtN.y) ||
! WriteItem( 230, vtN.z))
return false ;
// libero l'entit
delete vTxt[i] ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::AdjustText( string& sText)
{
// gestione del %
ReplaceString( sText, "%", "%%%") ;
// converto i byte della stringa in codici carattere
UINTVECTOR vCode ;
if ( ! GetCodePoints( sText, vCode))
return false ;
// ricostruisco la stringa dai codici
sText.clear() ;
for ( int i = 0 ; i < int( vCode.size()) ; ++ i) {
// caratteri ASCII stampabili
if ( vCode[i] >= 32 && vCode[i] <= 126)
sText += string( 1, vCode[i]) ;
// carattere speciale grado
else if ( vCode[i] == 176)
sText += "%%d" ;
// carattere speciale +/-
else if ( vCode[i] == 177)
sText += "%%p" ;
// carattere speciale diametro
else if ( vCode[i] == 216)
sText += "%%c" ;
// altri caratteri UNICODE
else
sText += "_" ;
}
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 ;
// spessore
double dThick = 0 ;
pLine->GetThickness( dThick) ;
if ( abs( dThick) > EPS_SMALL) {
if ( ! WriteItem( 39, dThick))
return false ;
}
// vettore estrusione
Vector3d vtExtr ;
pLine->GetExtrusion( vtExtr) ;
vtExtr.ToGlob( frFrame) ;
if ( ! vtExtr.IsSmall() && ! vtExtr.IsZplus()) {
if ( ! WriteItem( 210, vtExtr.x) ||
! WriteItem( 220, vtExtr.y) ||
! WriteItem( 230, vtExtr.z))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteCircle( const string& sLay, int nCol, const ICurveArc* pArc, const Frame3d& frFrame)
{
// verifico validit arco
if ( pArc == nullptr)
return false ;
// verifico verso eventuale estrusione
Vector3d vtN = pArc->GetNormVersor() ;
Vector3d vtExtr ;
pArc->GetExtrusion( vtExtr) ;
bool bExtrOpposite = AreOppositeVectorApprox( vtN, vtExtr) ;
// calcolo riferimento OCS
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 ;
// spessore
double dThick = 0 ;
pArc->GetThickness( dThick) ;
if ( abs( dThick) > EPS_SMALL) {
if ( ! WriteItem( 39, ( bExtrOpposite ? - dThick : dThick)))
return false ;
}
// vettore estrusione
if ( ! WriteItem( 210, vtN.x) ||
! WriteItem( 220, vtN.y) ||
! WriteItem( 230, vtN.z))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteArc( const string& sLay, int nCol, const ICurveArc* pArc, const Frame3d& frFrame)
{
// verifico validit arco
if ( pArc == nullptr)
return false ;
// verifico verso eventuale estrusione
Vector3d vtN = pArc->GetNormVersor() ;
Vector3d vtExtr ;
pArc->GetExtrusion( vtExtr) ;
bool bExtrOpposite = AreOppositeVectorApprox( vtN, vtExtr) ;
// calcolo riferimento OCS
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 ;
// spessore
double dThick = 0 ;
pArc->GetThickness( dThick) ;
if ( abs( dThick) > EPS_SMALL) {
if ( ! WriteItem( 39, ( bExtrOpposite ? - dThick : dThick)))
return false ;
}
// vettore estrusione
if ( ! WriteItem( 210, vtN.x) ||
! WriteItem( 220, vtN.y) ||
! WriteItem( 230, vtN.z))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteCurve2d( const string& sLay, int nCol, const ICurve* pCrv,
const Frame3d& frPlane, const Frame3d& frFrame)
{
// verifico validit curva
if ( pCrv == nullptr)
return false ;
// trasformo in poliarco
Frame3d frGlob ;
PolyArc PA ;
// se il piano non coincide con il piano XY globale, devo trasformare la curva
if ( ! AreSameFrame( frPlane, GLOB_FRM)) {
// creo una copia della curva (da buttare alla fine)
PtrOwner<ICurve> pModCrv( pCrv->Clone()) ;
if ( IsNull( pModCrv))
return false ;
// eseguo la trasformazione
pModCrv->ToLoc( frPlane) ;
// esplodo in archi
if ( ! pModCrv->ApproxWithArcs( BEZ_LIN_APPROX, BEZ_ANG_APPROX_DEG, PA))
return false ;
// calcolo il riferimento in cui sono espressi gli archi
frGlob = frPlane ;
frGlob.ToGlob( frFrame) ;
}
// altrimenti posso operare direttamente sulla curva originale
else {
// esplodo in archi
if ( ! pCrv->ApproxWithArcs( BEZ_LIN_APPROX, BEZ_ANG_APPROX_DEG, PA))
return false ;
// assegno il riferimento in cui sono espressi gli archi
frGlob = frFrame ;
}
// calcolo il riferimento OCS con la stessa Z del riferimento degli archi
Frame3d frOCS ;
frOCS.Set( ORIG, frGlob.VersZ()) ;
// esporto come polyline 2d
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 per sola elevazione : X,Y inutili Z elevazione
Point3d ptE = ORIG ;
ptE.LocToLoc( frGlob, frOCS) ;
if ( ! WriteItem( 10, 0) ||
! WriteItem( 20, 0) ||
! WriteItem( 30, ptE.z))
return false ;
// flag
bool bClosed = pCrv->IsClosed() ;
if ( ! WriteItem( 70, ( bClosed ? 1 : 0)))
return false ;
// spessore
double dThick = 0 ;
pCrv->GetThickness( dThick) ;
if ( abs( dThick) > EPS_SMALL) {
if ( ! WriteItem( 39, dThick))
return false ;
}
// vettore estrusione ( versore Z di OCS)
if ( ! WriteItem( 210, frGlob.VersZ().x) ||
! WriteItem( 220, frGlob.VersZ().y) ||
! WriteItem( 230, frGlob.VersZ().z))
return false ;
// emetto i vertici
double dBulge ;
Point3d ptP ;
for ( bool bPnt = PA.GetFirstPoint( ptP, dBulge) ;
bPnt ;
bPnt = PA.GetNextPoint( ptP, dBulge, bClosed)) {
// entit vertice
if ( ! WriteItem( 0, "VERTEX"))
return false ;
// layer
if ( ! WriteItem( 8, sLay))
return false ;
// punto corrente
ptP.LocToLoc( frGlob, frOCS) ;
if ( ! WriteItem( 10, ptP.x) ||
! WriteItem( 20, ptP.y) ||
! WriteItem( 30, ptP.z))
return false ;
// bulge
if ( ! WriteItem( 42, dBulge))
return false ;
// flag
if ( ! WriteItem( 70, 0))
return false ;
}
// entit termine dei vertici
if ( ! WriteItem( 0, "SEQEND"))
return false ;
// layer
if ( ! WriteItem( 8, sLay))
return false ;
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, ICurve::APL_SPECIAL, PL))
return false ;
// recupero lo spessore
double dThick = 0 ;
pCrv->GetThickness( dThick) ;
// recupero il vettore estrusione
Vector3d vtExtr ;
pCrv->GetExtrusion( vtExtr) ;
vtExtr.ToGlob( frFrame) ;
// se senza spessore o con estrusione nulla, polilinea 3d
if ( abs( dThick) < EPS_SMALL || vtExtr.IsSmall()) {
// 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 ;
}
// altrimenti insieme di segmenti di retta
else {
Point3d ptStart, ptEnd ;
for ( bool bPnt = PL.GetFirstLine( ptStart, ptEnd) ;
bPnt ;
bPnt = PL.GetNextLine( ptStart, ptEnd)) {
// identificativo entit
if ( ! WriteItem( 0, "LINE"))
return false ;
// layer
if ( ! WriteItem( 8, sLay))
return false ;
// colore
if ( ! WriteItem( 62, nCol))
return false ;
// punto iniziale
ptStart.ToGlob( frFrame) ;
if ( ! WriteItem( 10, ptStart.x) ||
! WriteItem( 20, ptStart.y) ||
! WriteItem( 30, ptStart.z))
return false ;
// punto finale
ptEnd.ToGlob( frFrame) ;
if ( ! WriteItem( 11, ptEnd.x) ||
! WriteItem( 21, ptEnd.y) ||
! WriteItem( 31, ptEnd.z))
return false ;
// spessore
if ( abs( dThick) > EPS_SMALL) {
if ( ! WriteItem( 39, dThick))
return false ;
}
// vettore estrusione
if ( ! vtExtr.IsZplus()) {
if ( ! WriteItem( 210, vtExtr.x) ||
! WriteItem( 220, vtExtr.y) ||
! WriteItem( 230, vtExtr.z))
return false ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::TestFilter( int nLev, int nMode, int nStat, bool bGroup)
{
int nFilter = bGroup ? m_nGroupFilter : m_nFilter ;
if ( ( nLev == GDB_LV_USER && ( nFilter & EEXFLT_LEVUSER) == 0) ||
( nLev == GDB_LV_SYSTEM && ( nFilter & EEXFLT_LEVSYSTEM) == 0) ||
( nLev == GDB_LV_TEMP && ( nFilter & EEXFLT_LEVTEMP) == 0))
return false ;
if ( ( nMode == GDB_MD_STD && ( nFilter & EEXFLT_MODESTD) == 0) ||
( nMode == GDB_MD_LOCKED && ( nFilter & EEXFLT_MODELOCKED) == 0) ||
( nMode == GDB_MD_HIDDEN && ( nFilter & EEXFLT_MODEHIDDEN) == 0))
return false ;
if ( ( nStat == GDB_ST_OFF && ( nFilter & EEXFLT_STAOFF) == 0) ||
( nStat == GDB_ST_ON && ( nFilter & EEXFLT_STAON) == 0) ||
( nStat == GDB_ST_SEL && ( nFilter & EEXFLT_STASEL) == 0))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::CalcGroupFilter( void)
{
m_nGroupFilter = 0 ;
// Status
if ( ( m_nFilter & EEXFLT_STASEL) != 0)
m_nGroupFilter += EEXFLT_STASEL + EEXFLT_STAOFF + EEXFLT_STAON ;
else if ( ( m_nFilter & EEXFLT_STAOFF) != 0)
m_nGroupFilter += EEXFLT_STAOFF + EEXFLT_STAON ;
else
m_nGroupFilter += EEXFLT_STAON ;
// Mode
if ( ( m_nFilter & EEXFLT_MODELOCKED) != 0)
m_nGroupFilter += EEXFLT_MODELOCKED + EEXFLT_MODEHIDDEN + EEXFLT_MODESTD ;
else if ( ( m_nFilter & EEXFLT_MODEHIDDEN) != 0)
m_nGroupFilter += EEXFLT_MODEHIDDEN + EEXFLT_MODESTD ;
else
m_nGroupFilter += EEXFLT_MODESTD ;
// Level
if ( ( m_nFilter & EEXFLT_LEVSYSTEM) != 0)
m_nGroupFilter += EEXFLT_LEVSYSTEM + EEXFLT_LEVTEMP + EEXFLT_LEVUSER ;
else if ( ( m_nFilter & EEXFLT_LEVTEMP) != 0)
m_nGroupFilter += EEXFLT_LEVTEMP + EEXFLT_LEVUSER ;
else
m_nGroupFilter += EEXFLT_LEVUSER ;
return true ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteItem( int nCode, int nVal)
{
bool bOk = m_Writer.OutText(( nCode < 10 ? " " : nCode < 100 ? " " : "") + ToString( nCode)) ;
bOk = bOk && m_Writer.OutText( ToString( nVal)) ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteItem( int nCode, double dVal, int nPrec)
{
bool bOk = m_Writer.OutText(( nCode < 10 ? " " : nCode < 100 ? " " : "") + ToString( nCode)) ;
bOk = bOk && m_Writer.OutText( ToString( dVal, nPrec)) ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
ExportDxf::WriteItem( int nCode, const string& sVal)
{
bool bOk = m_Writer.OutText(( nCode < 10 ? " " : nCode < 100 ? " " : "") + ToString( nCode)) ;
bOk = bOk && m_Writer.OutText( sVal) ;
return bOk ;
}
//----------------------------------------------------------------------------
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 ;
}
ValidateDxfName( sNewLay, m_bAdvancedNames) ;
ToUpper( sNewLay) ;
return sNewLay ;
}
//----------------------------------------------------------------------------
string
ExportDxf::FontNameToStyle( const string& sFontName)
{
string sStyle = sFontName ;
// se Nfe sostituisco con shx
if ( FileExtensionMatches( sStyle, "NFE")) {
sStyle.erase( sStyle.size() - 4, 4) ;
sStyle += "_shx" ;
}
return sStyle ;
}
//----------------------------------------------------------------------------
string
ExportDxf::AdjustFontName( const string& sFontName)
{
string sStyle = sFontName ;
// se Nfe sostituisco con shx
if ( FileExtensionMatches( sStyle, "NFE")) {
sStyle.erase( sStyle.size() - 4, 4) ;
sStyle += ".shx" ;
}
return sStyle ;
}