f54f1f8969
- aggiunta importazione formato OFF (Object File Format).
2048 lines
66 KiB
C++
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 ;
|
|
}
|
|
|