df864c93a8
- adattamenti e ricompilazione per passaggio a C++ 20
970 lines
33 KiB
C++
970 lines
33 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : ImportCsf.cpp Data : 17.05.15 Versione : 1.6e3
|
|
// Contenuto : Implementazione della classe per l'importazione di CSF.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 17.05.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "ImportCsf.h"
|
|
#include "DllMain.h"
|
|
#include "/EgtDev/Include/EExDllMain.h"
|
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
|
#include "/EgtDev/Include/EGkCurveLine.h"
|
|
#include "/EgtDev/Include/EGkCurveArc.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkCurveAux.h"
|
|
#include "/EgtDev/Include/EGkExtText.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
#include "/EgtDev/Include/EGnFileUtils.h"
|
|
#include "/EgtDev/Include/EgtStringConverter.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include <fstream>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string INF_TH = "Th" ;
|
|
const string INF_SIDE = "Side" ;
|
|
const string INF_LBL = "Lbl" ;
|
|
const string INF_ATTR = "Attr" ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
struct ExtendedText {
|
|
double dH ; // altezza del carattere
|
|
double dRat ; // rapporto altezza/larghezza
|
|
int nWeight ; // peso
|
|
int nColor ; // colore
|
|
bool bItalic ; // italico
|
|
bool bUnderline ; // sottolineato
|
|
bool bStrikeout ; // barrato
|
|
std::string sFont ; // nome del font
|
|
std::string sText ; // stringa di testo
|
|
PNTVECTOR vPnt ; // vettore dei punti di inserimento
|
|
DBLVECTOR vAng ; // vettore degli angoli
|
|
|
|
ExtendedText( void) : dH( 0), dRat( 0), nWeight( 400), nColor( 0),
|
|
bItalic( false), bUnderline( false), bStrikeout( false) {}
|
|
} ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
IImportCsf*
|
|
CreateImportCsf( void)
|
|
{
|
|
// verifico la chiave e le opzioni
|
|
if ( ! VerifyKey( KEYOPT_EEX_INPBASE))
|
|
return nullptr ;
|
|
// creo l'oggetto
|
|
return static_cast<IImportCsf*> ( new(nothrow) ImportCsf) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ImportCsf::ImportCsf( void)
|
|
{
|
|
m_pGDB = nullptr ;
|
|
m_bIsMM = true ;
|
|
m_dThick = 0 ;
|
|
m_nCurrPart = - 1 ;
|
|
m_nCurrLay = - 1 ;
|
|
m_nCurrPartId = GDB_ID_NULL ;
|
|
m_nCurrLayId = GDB_ID_NULL ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::Import( const string& sFile, IGeomDB* pGDB)
|
|
{
|
|
// verifico il DB geometrico
|
|
if ( pGDB == nullptr) {
|
|
LOG_ERROR( GetEExLogger(), "ImportCsf : Error on GeomDB")
|
|
return false ;
|
|
}
|
|
m_pGDB = pGDB ;
|
|
|
|
// nomi dei file
|
|
string sHedFile = ChangeFileExtension( sFile, "hed") ;
|
|
string sEntFile = ChangeFileExtension( sFile, "ent") ;
|
|
string sEnsFile = ChangeFileExtension( sFile, "ens") ;
|
|
|
|
// apertura del file delle entità
|
|
ifstream InEntFile ;
|
|
InEntFile.open( stringtoW( sEntFile), ios::in | ios::binary) ;
|
|
if ( InEntFile.fail()) {
|
|
string sErr = "ImportCsf : Error opening " + sEntFile ;
|
|
LOG_ERROR( GetEExLogger(), sErr.c_str())
|
|
return false ;
|
|
}
|
|
|
|
// apertura del secondo file delle entità
|
|
m_InEnsFile.open( stringtoW( sEnsFile), ios::in | ios::binary) ;
|
|
if ( m_InEnsFile.fail()) {
|
|
string sErr = "ImportCsf : Error opening " + sEnsFile ;
|
|
LOG_ERROR( GetEExLogger(), sErr.c_str())
|
|
// non è detto sia un errore, potrebbe non essere necessario
|
|
}
|
|
|
|
// lettura dell'header
|
|
bool bOk = ReadHeader( sHedFile) ;
|
|
|
|
// lettura di eventuali attributi
|
|
bOk = ReadAttribs() && bOk ;
|
|
|
|
// impostazione del colore di default nero
|
|
m_pGDB->SetDefaultMaterial( BLACK) ;
|
|
|
|
// ciclo di lettura delle entità
|
|
while ( true) {
|
|
// lettura
|
|
CsfEnt csfEnt ;
|
|
InEntFile.read( reinterpret_cast<char*>( &csfEnt), CSFENT_SIZE) ;
|
|
if ( InEntFile.gcount() != CSFENT_SIZE)
|
|
break ;
|
|
// interpretazione
|
|
if ( ! ProcessEntity( csfEnt)) {
|
|
bOk = false ;
|
|
string sErr = "ImportCsf : Error on Entity" ;
|
|
LOG_ERROR( GetEExLogger(), sErr.c_str())
|
|
}
|
|
}
|
|
|
|
// chiusura dei file
|
|
InEntFile.close() ;
|
|
m_InEnsFile.close() ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ReadHeader( const string& sHedFile)
|
|
{
|
|
// apertura del file di intestazione
|
|
ifstream InHedFile ;
|
|
InHedFile.open( stringtoW( sHedFile), ios::in | ios::binary) ;
|
|
if ( InHedFile.fail()) {
|
|
string sErr = "ImportCsf : Error opening " + sHedFile ;
|
|
LOG_ERROR( GetEExLogger(), sErr.c_str())
|
|
return false ;
|
|
}
|
|
|
|
// lettura dei dati
|
|
CsfHeader csfHed ;
|
|
InHedFile.read( reinterpret_cast<char*>( &csfHed), CSFHEADER_SIZE) ;
|
|
bool bOk = ( InHedFile.gcount() == CSFHEADER_SIZE) ;
|
|
|
|
// imposto unità di misura e spessore di progetto
|
|
m_bIsMM = ( csfHed.nUnits == 1) ;
|
|
m_dThick = - ConvertToMM( csfHed.dThick) ;
|
|
|
|
// chiusura del file
|
|
InHedFile.close() ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ReadAttribs( void)
|
|
{
|
|
// verifico che il secondo file delle entità sia aperto
|
|
if ( ! m_InEnsFile.is_open())
|
|
return false ;
|
|
|
|
// mi porto all'inizio del file
|
|
m_InEnsFile.seekg( 0) ;
|
|
if ( m_InEnsFile.fail())
|
|
return false ;
|
|
|
|
// lettura del numero degli attributi
|
|
int nAttribNbr ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( &nAttribNbr), sizeof( nAttribNbr)) ;
|
|
if ( m_InEnsFile.gcount() != sizeof( nAttribNbr))
|
|
return false ;
|
|
|
|
// se non ci sono attributi, posso uscire
|
|
if ( nAttribNbr == 0)
|
|
return true ;
|
|
|
|
// preparo spazio per gli attributi
|
|
try { m_vAttrib.reserve( nAttribNbr) ; }
|
|
catch(...) { return false ; }
|
|
|
|
// leggo gli attributi
|
|
for ( int i = 0 ; i < nAttribNbr ; ++ i) {
|
|
// lettura
|
|
Attrib attr ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( &attr), ATTRIB_SIZE) ;
|
|
if ( m_InEnsFile.gcount() != ATTRIB_SIZE)
|
|
return false ;
|
|
// inserimento nel vettore
|
|
m_vAttrib.push_back( attr) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessEntity( const CsfEnt& csfEnt)
|
|
{
|
|
switch ( csfEnt.nType) {
|
|
case 2 : // Linea
|
|
return ProcessLine( csfEnt) ;
|
|
case 3 : // Arco orario
|
|
case 4 : // Arco antiorario
|
|
return ProcessArc( csfEnt) ;
|
|
case 6 : // Foro
|
|
return ProcessHole( csfEnt) ;
|
|
case 8 : // Testo
|
|
return ProcessText( csfEnt) ;
|
|
case 11 : // Rettangolo
|
|
return ProcessRectangle( csfEnt) ;
|
|
case 12 : // Ellisse
|
|
return ProcessEllipse( csfEnt) ;
|
|
case 14 : // Proprietà
|
|
return ProcessProperty( csfEnt) ;
|
|
case 16 : // Curva Nurbs
|
|
return ProcessCNurbs( csfEnt) ;
|
|
case 28 : // Testo esteso
|
|
return ProcessExtendedText( csfEnt) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessLine( const CsfEnt& csfEnt)
|
|
{
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// creo la linea
|
|
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
|
|
if ( IsNull( pCrvLine))
|
|
return false ;
|
|
// setto la linea
|
|
if ( ! pCrvLine->Set( ConvertToPointMM( csfEnt.dP1x, csfEnt.dP1y, csfEnt.dP1z),
|
|
ConvertToPointMM( csfEnt.dP2x, csfEnt.dP2y, csfEnt.dP2z)))
|
|
return false ;
|
|
// inserisco la linea nel DB
|
|
bool bSingle = ( csfEnt.nPart == 0) ;
|
|
return AddCurve( Release( pCrvLine), nGrpId, csfEnt.nPar2, bSingle) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessArc( const CsfEnt& csfEnt)
|
|
{
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// creo l'arco
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( IsNull( pCrvArc))
|
|
return false ;
|
|
// setto l'arco
|
|
if ( ! pCrvArc->Set2PRS( ConvertToPointMM( csfEnt.dP1x, csfEnt.dP1y, csfEnt.dP1z),
|
|
ConvertToPointMM( csfEnt.dP2x, csfEnt.dP2y, csfEnt.dP2z),
|
|
ConvertToMM( csfEnt.dRad), ( csfEnt.nType == 4)))
|
|
return false ;
|
|
// inserisco l'arco nel DB
|
|
bool bSingle = ( csfEnt.nPart == 0) ;
|
|
return AddCurve( Release( pCrvArc), nGrpId, csfEnt.nPar2, bSingle) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessHole( const CsfEnt& csfEnt)
|
|
{
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// creo la circonferenza
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( IsNull( pCrvArc))
|
|
return false ;
|
|
// setto la circonferenza
|
|
Point3d ptTop = ConvertToPointMM( csfEnt.dP1x, csfEnt.dP1y, csfEnt.dP1z) ;
|
|
Point3d ptBot = ConvertToPointMM( csfEnt.dP2x, csfEnt.dP2y, csfEnt.dP2z) ;
|
|
Vector3d vtExtr = ptTop - ptBot ;
|
|
double dRad = ConvertToMM( csfEnt.dCenx) ;
|
|
if ( ! pCrvArc->Set( ptTop, vtExtr, dRad) ||
|
|
! pCrvArc->SetExtrusion( vtExtr) ||
|
|
! pCrvArc->SetThickness( - vtExtr.Len()))
|
|
return false ;
|
|
// inserisco la circonferenza nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGrpId, Release( pCrvArc)) ;
|
|
return ( nId != GDB_ID_NULL && AddEntAttrib( nId, 1, csfEnt.nPar2)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessText( const CsfEnt& csfEnt)
|
|
{
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// creo il testo
|
|
PtrOwner<IExtText> pTxt( CreateExtText()) ;
|
|
if ( IsNull( pTxt))
|
|
return false ;
|
|
// assegno i dati
|
|
Point3d ptP = ConvertToPointMM( csfEnt.dP1x, csfEnt.dP1y, csfEnt.dP1z) ;
|
|
// la stringa di testo occupa i successivi 40 caratteri dell'entità
|
|
const char* szText = reinterpret_cast<const char*>( &csfEnt.dP2x) ;
|
|
// controllo non superi i 39 caratteri di lunghezza (più NULL finale)
|
|
if ( strnlen( szText, 40) == 40)
|
|
return false ;
|
|
string sText = szText ;
|
|
double dH = ConvertToMM( csfEnt.dCenz) ;
|
|
double dRat = csfEnt.dAng1Deg ;
|
|
double dAng = csfEnt.dAng2Deg ;
|
|
if ( ! pTxt->Set( ptP, Z_AX, FromPolar( 1, dAng), sText, "", 400, false, dH, dRat, 0))
|
|
return false ;
|
|
// inserisco il testo nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGrpId, Release( pTxt)) ;
|
|
return ( nId != GDB_ID_NULL && AddEntAttrib( nId, 1, csfEnt.nPar2)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessRectangle( const CsfEnt& csfEnt)
|
|
{
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// creo la curva composita
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCompo))
|
|
return false ;
|
|
// recupero centro e semiassi del rettangolo
|
|
Point3d ptCen = ConvertToPointMM( csfEnt.dP1x, csfEnt.dP1y, csfEnt.dP1z) ;
|
|
Vector3d vtMajSax = ConvertToVectorMM( csfEnt.dP2x, csfEnt.dP2y, csfEnt.dP2z) ;
|
|
Vector3d vtMinSax = ConvertToVectorMM( csfEnt.dCenx, csfEnt.dCeny, csfEnt.dCenz) ;
|
|
if ( vtMajSax.IsSmall() || vtMinSax.IsSmall())
|
|
return false ;
|
|
// profondità
|
|
double dThick = - ConvertToMM( csfEnt.dAng1Deg) ;
|
|
// recupero tipo vertici e raggio raccordo o distanza smusso
|
|
#pragma pack(2)
|
|
struct VertRad { short nVert ; double dRad ; } ;
|
|
#pragma pack()
|
|
VertRad& VR = (VertRad&) csfEnt.dAng2Deg ;
|
|
int nVert = VR.nVert ;
|
|
double dRad = ConvertToMM( VR.dRad) ;
|
|
// definisco poliarco
|
|
PolyArc PA ;
|
|
// se spigoli vivi (0)
|
|
if ( nVert == 0) {
|
|
PA.AddUPoint( 0, ptCen - vtMajSax - vtMinSax, 0) ;
|
|
PA.AddUPoint( 1, ptCen + vtMajSax - vtMinSax, 0) ;
|
|
PA.AddUPoint( 2, ptCen + vtMajSax + vtMinSax, 0) ;
|
|
PA.AddUPoint( 3, ptCen - vtMajSax + vtMinSax, 0) ;
|
|
PA.Close() ;
|
|
}
|
|
// altrimenti raccordi (1) o smussi (2)
|
|
else {
|
|
Vector3d vtMajDelt = vtMajSax * dRad / vtMajSax.Len() ;
|
|
Vector3d vtMinDelt = vtMinSax * dRad / vtMinSax.Len() ;
|
|
double dCornBulge = ( ( nVert == 1) ? ( SQRT2 - 1) : 0) ;
|
|
PA.AddUPoint( 0, ptCen - vtMajSax - vtMinSax + vtMajDelt, 0) ;
|
|
PA.AddUPoint( 1, ptCen + vtMajSax - vtMinSax - vtMajDelt, dCornBulge) ;
|
|
PA.AddUPoint( 2, ptCen + vtMajSax - vtMinSax + vtMinDelt, 0) ;
|
|
PA.AddUPoint( 3, ptCen + vtMajSax + vtMinSax - vtMinDelt, dCornBulge) ;
|
|
PA.AddUPoint( 4, ptCen + vtMajSax + vtMinSax - vtMajDelt, 0) ;
|
|
PA.AddUPoint( 5, ptCen - vtMajSax + vtMinSax + vtMajDelt, dCornBulge) ;
|
|
PA.AddUPoint( 6, ptCen - vtMajSax + vtMinSax - vtMinDelt, 0) ;
|
|
PA.AddUPoint( 7, ptCen - vtMajSax - vtMinSax + vtMinDelt, dCornBulge) ;
|
|
PA.Close() ;
|
|
}
|
|
// costruisco la curva composita
|
|
if ( ! pCompo->FromPolyArc( PA))
|
|
return false ;
|
|
// assegno estrusione e spessore
|
|
if ( abs( dThick) > EPS_SMALL) {
|
|
pCompo->SetExtrusion( Z_AX) ;
|
|
pCompo->SetThickness( dThick) ;
|
|
}
|
|
// sposto inizio a metà del primo lato
|
|
pCompo->ChangeStartPoint( 0.5) ;
|
|
// recupero numero di curve componenti
|
|
int nCrvNbr = pCompo->GetCurveCount() ;
|
|
// inserisco la curva composita nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGrpId, Release( pCompo)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// aggiungo eventuale attributo di entità
|
|
for ( int i = 1 ; i <= nCrvNbr ; ++ i)
|
|
AddEntAttrib( nId, i, csfEnt.nPar2) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessEllipse( const CsfEnt& csfEnt)
|
|
{
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// creo la curva composita
|
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCompo))
|
|
return false ;
|
|
// recupero centro e semiassi dell'ellisse
|
|
Point3d ptCen = ConvertToPointMM( csfEnt.dP1x, csfEnt.dP1y, csfEnt.dP1z) ;
|
|
Vector3d vtMajSax = ConvertToVectorMM( csfEnt.dP2x, csfEnt.dP2y, csfEnt.dP2z) ;
|
|
Vector3d vtMinSax = ConvertToVectorMM( csfEnt.dCenx, csfEnt.dCeny, csfEnt.dCenz) ;
|
|
if ( vtMajSax.IsSmall() || vtMinSax.IsSmall())
|
|
return false ;
|
|
// profondità
|
|
double dThick = - ConvertToMM( csfEnt.dAng1Deg) ;
|
|
// creo curva composita formata da circonferenza di semiasse minore
|
|
PolyArc PA ;
|
|
PA.AddUPoint( 0, ptCen - vtMinSax, 1) ;
|
|
PA.AddUPoint( 0, ptCen + vtMinSax, 1) ;
|
|
PA.Close() ;
|
|
// costruisco la curva composita
|
|
if ( ! pCompo->FromPolyArc( PA))
|
|
return false ;
|
|
// eseguo scalatura non uniforme
|
|
Frame3d frFrame ;
|
|
frFrame.Set( ptCen, ptCen + vtMajSax, ptCen + vtMinSax) ;
|
|
if ( ! pCompo->Scale( frFrame, vtMajSax.Len() / vtMinSax.Len(), 1, 1))
|
|
return false ;
|
|
// assegno estrusione e spessore
|
|
if ( abs( dThick) > EPS_SMALL) {
|
|
pCompo->SetExtrusion( Z_AX) ;
|
|
pCompo->SetThickness( dThick) ;
|
|
}
|
|
// recupero numero di curve componenti
|
|
int nCrvNbr = pCompo->GetCurveCount() ;
|
|
// inserisco la curva composita nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGrpId, Release( pCompo)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// aggiungo eventuale attributo di entità
|
|
for ( int i = 1 ; i <= nCrvNbr ; ++ i)
|
|
AddEntAttrib( nId, i, csfEnt.nPar2) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessProperty( const CsfEnt& csfEnt)
|
|
{
|
|
// tipi di proprietà
|
|
const int PROP_COLOR = 1 ;
|
|
const int PROP_5A_ATTRIB = 2 ;
|
|
const int PROP_VIEW_POINT = 3 ;
|
|
const int PROP_FRAME = 4 ;
|
|
const int PROP_ATTRIB = 5 ;
|
|
// ignoro la proprietà punto di vista
|
|
if ( csfEnt.nPar1 == PROP_VIEW_POINT)
|
|
return true ;
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// assegno la proprietà caratteristica
|
|
switch ( csfEnt.nPar1) {
|
|
case PROP_COLOR :
|
|
// colore di percorso
|
|
if ( csfEnt.nPar3 == 0) {
|
|
Color cCol = CalcColor( csfEnt.nPar2) ;
|
|
m_pGDB->SetMaterial( nGrpId, cCol) ;
|
|
}
|
|
union { short i[4] ; double d ; } dVal ;
|
|
dVal.d = csfEnt.dP1x ;
|
|
// spessore di percorso
|
|
if ( dVal.i[0] != 0)
|
|
m_pGDB->SetInfo( nGrpId, INF_TH, - ConvertToMM( csfEnt.dP1y)) ;
|
|
// lato di correzione
|
|
if ( dVal.i[1] != 0)
|
|
m_pGDB->SetInfo( nGrpId, INF_SIDE, dVal.i[1]) ;
|
|
return true ;
|
|
case PROP_FRAME :
|
|
{ Frame3d frFrame ;
|
|
if ( ! frFrame.Set( ConvertToPointMM( csfEnt.dP1x, csfEnt.dP1y, csfEnt.dP1z),
|
|
Vector3d( csfEnt.dAng1Deg, csfEnt.dAng2Deg, csfEnt.dRad),
|
|
Vector3d( csfEnt.dP2x, csfEnt.dP2y, csfEnt.dP2z)))
|
|
return false ;
|
|
*(m_pGDB->GetGroupFrame( nGrpId)) = frFrame ; }
|
|
return true ;
|
|
case PROP_ATTRIB :
|
|
{ // la stringa occupa gli ultimi 40 caratteri dell'entità
|
|
const char* szLabel = reinterpret_cast<const char*>( &csfEnt.dCeny) ;
|
|
// controllo non superi i 39 caratteri di lunghezza (più NULL finale)
|
|
if ( strnlen( szLabel, 40) == 40)
|
|
return false ;
|
|
m_pGDB->SetInfo( nGrpId, INF_LBL, string( szLabel)) ; }
|
|
return true ;
|
|
default :
|
|
return true ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessCNurbs( const CsfEnt& csfEnt)
|
|
{
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero offset da inizio dei dati nel file ENS
|
|
#pragma pack(2)
|
|
struct PosSize { int nPos ; int nSize ; } ;
|
|
#pragma pack()
|
|
PosSize& PS = (PosSize&) csfEnt.dRad ;
|
|
int nPos = PS.nPos ;
|
|
// leggo i dati dal file ENS
|
|
CNurbsData cnData ;
|
|
if ( ! ReadCNurbsData( nPos, cnData))
|
|
return false ;
|
|
// rendo canonica la rappresentazione della curva Nurbs
|
|
if ( ! NurbsCurveCanonicalize( cnData))
|
|
return false ;
|
|
// creo la curva equivalente alla Nurbs
|
|
PtrOwner<ICurve> pCrv( NurbsToBezierCurve( cnData)) ;
|
|
if ( IsNull( pCrv))
|
|
return false ;
|
|
if ( ! pCrv->IsValid())
|
|
return true ;
|
|
// inserisco la curva nel DB
|
|
// inserisco l'arco nel DB
|
|
bool bSingle = ( csfEnt.nPart == 0) ;
|
|
return AddCurve( Release( pCrv), nGrpId, csfEnt.nPar2, bSingle) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ProcessExtendedText( const CsfEnt& csfEnt)
|
|
{
|
|
// recupero il gruppo di inserimento
|
|
int nGrpId = GetPartLayerId( csfEnt.nPart, csfEnt.nPath) ;
|
|
if ( nGrpId == GDB_ID_NULL)
|
|
return false ;
|
|
// recupero offset da inizio dei dati nel file ENS
|
|
#pragma pack(2)
|
|
struct PosSize { int nDummy ; int nPos ; int nSize ; } ;
|
|
#pragma pack()
|
|
PosSize& PS = (PosSize&) csfEnt.dCenx ;
|
|
int nPos = PS.nPos ;
|
|
// leggo i dati dal file ENS
|
|
ExtendedText etData ;
|
|
if ( ! ReadExtendedTextData( nPos, etData))
|
|
return false ;
|
|
// coefficienti correttivi empirici
|
|
etData.dH *= 0.60 ;
|
|
etData.dRat *= 1.75 ;
|
|
// salvataggio testo con singolo punto di inserimento
|
|
if ( etData.vPnt.size() == 1) {
|
|
// creo il testo
|
|
PtrOwner<IExtText> pTxt( CreateExtText()) ;
|
|
if ( IsNull( pTxt))
|
|
return false ;
|
|
// assegno i dati
|
|
if ( ! pTxt->Set( etData.vPnt[0], Z_AX, FromPolar( 1, etData.vAng[0]),
|
|
etData.sText, etData.sFont, etData.nWeight, etData.bItalic, etData.dH, etData.dRat, 0))
|
|
return false ;
|
|
// inserisco il testo nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGrpId, Release( pTxt)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// assegno il colore (se non default)
|
|
if ( etData.nColor != 0) {
|
|
Color cCol = CalcColor( etData.nColor) ;
|
|
m_pGDB->SetMaterial( nId, cCol) ;
|
|
}
|
|
// assegno eventuale attributo di entità
|
|
AddEntAttrib( nId, 1, csfEnt.nPar2) ;
|
|
return true ;
|
|
}
|
|
// salvataggio testo con un punto di inserimento per ogni carattere
|
|
else if ( etData.sText.size() == etData.vPnt.size()) {
|
|
for ( int i = 0 ; i < ssize( etData.sText) ; ++ i) {
|
|
// creo il testo
|
|
PtrOwner<IExtText> pTxt( CreateExtText()) ;
|
|
if ( IsNull( pTxt))
|
|
return false ;
|
|
// assegno i dati
|
|
if ( ! pTxt->Set( etData.vPnt[i], Z_AX, FromPolar( 1, etData.vAng[i]),
|
|
etData.sText.substr( i, 1), etData.sFont, etData.nWeight, etData.bItalic, etData.dH, etData.dRat, 0))
|
|
return false ;
|
|
// inserisco il testo nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGrpId, Release( pTxt)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// assegno il colore (se non default)
|
|
if ( etData.nColor != 0) {
|
|
Color cCol = CalcColor( etData.nColor) ;
|
|
m_pGDB->SetMaterial( nId, cCol) ;
|
|
}
|
|
// assegno eventuale attributo di entità
|
|
AddEntAttrib( nId, 1, csfEnt.nPar2) ;
|
|
}
|
|
return true ;
|
|
}
|
|
// altrimenti errore
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
ImportCsf::ConvertToMM( double dVal)
|
|
{
|
|
return ( m_bIsMM ? dVal : dVal * ONEINCH) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Point3d
|
|
ImportCsf::ConvertToPointMM( double dX, double dY, double dZ)
|
|
{
|
|
if ( m_bIsMM)
|
|
return Point3d( dX, dY, dZ) ;
|
|
else
|
|
return Point3d( dX, dY, dZ) * ONEINCH ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Vector3d
|
|
ImportCsf::ConvertToVectorMM( double dX, double dY, double dZ)
|
|
{
|
|
if ( m_bIsMM)
|
|
return Vector3d( dX, dY, dZ) ;
|
|
else
|
|
return Vector3d( dX, dY, dZ) * ONEINCH ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ImportCsf::GetPartLayerId( int nPart, int nPath)
|
|
{
|
|
// se indici non validi
|
|
if ( nPart < 0 || nPath < 0)
|
|
return GDB_ID_NULL ;
|
|
// se il pezzo non è quello corrente
|
|
if ( nPart != m_nCurrPart) {
|
|
// cerco il pezzo con il nome desiderato
|
|
int nPartId = m_pGDB->GetFirstNameInGroup( GDB_ID_ROOT, ToString( nPart)) ;
|
|
// se non trovato, lo creo
|
|
if ( nPartId == GDB_ID_NULL) {
|
|
nPartId = m_pGDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ;
|
|
if ( nPartId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
m_pGDB->SetName( nPartId, ToString( nPart)) ;
|
|
}
|
|
m_nCurrPart = nPart ;
|
|
m_nCurrPartId = nPartId ;
|
|
m_nCurrLay = - 1 ;
|
|
m_nCurrLayId = GDB_ID_NULL ;
|
|
}
|
|
// se il layer non è quello corrente (ma il pezzo qui sicuramente lo è)
|
|
if ( nPath != m_nCurrLay) {
|
|
// cerco il layer con il nome desiderato
|
|
int nLayId = m_pGDB->GetFirstNameInGroup( m_nCurrPartId, ToString( nPath)) ;
|
|
// se non trovato, lo creo
|
|
if ( nLayId == GDB_ID_NULL) {
|
|
nLayId = m_pGDB->AddGroup( GDB_ID_NULL, m_nCurrPartId, GLOB_FRM) ;
|
|
if ( nLayId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
m_pGDB->SetName( nLayId, ToString( nPath)) ;
|
|
}
|
|
// assegno i valori correnti e ritorno l'id del layer
|
|
m_nCurrLay = nPath ;
|
|
m_nCurrLayId = nLayId ;
|
|
}
|
|
// pezzo e layer cercati devono ora coincidere con quelli correnti
|
|
return m_nCurrLayId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Color
|
|
ImportCsf::CalcColor( int nInd)
|
|
{
|
|
switch ( nInd) {
|
|
default :
|
|
return Color( 0.0, 0.0, 0.0, 1.0) ;
|
|
case 1 :
|
|
return Color( 0.0, 0.0, 0.5, 1.0) ;
|
|
case 2 :
|
|
return Color( 0.0, 0.5, 0.0, 1.0) ;
|
|
case 3 :
|
|
return Color( 0.0, 0.5, 0.5, 1.0) ;
|
|
case 4 :
|
|
return Color( 0.5, 0.0, 0.0, 1.0) ;
|
|
case 5 :
|
|
return Color( 0.5, 0.0, 0.5, 1.0) ;
|
|
case 6 :
|
|
return Color( 0.5, 0.5, 0.0, 1.0) ;
|
|
case 7 :
|
|
return Color( 0.75, 0.75, 0.75, 1.0) ;
|
|
case 8 :
|
|
return Color( 0.5, 0.5, 0.5, 1.0) ;
|
|
case 9 :
|
|
return Color( 0.0, 0.0, 1.0, 1.0) ;
|
|
case 10 :
|
|
return Color( 0.0, 1.0, 0.0, 1.0) ;
|
|
case 11 :
|
|
return Color( 0.0, 1.0, 1.0, 1.0) ;
|
|
case 12 :
|
|
return Color( 1.0, 0.0, 0.0, 1.0) ;
|
|
case 13 :
|
|
return Color( 1.0, 0.0, 1.0, 1.0) ;
|
|
case 14 :
|
|
return Color( 1.0, 1.0, 0.0, 1.0) ;
|
|
case 15 :
|
|
return Color( 1.0, 1.0, 1.0, 1.0) ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::AddCurve( ICurve* pCrv, int nGrpId, int nAttribId, bool bSingle)
|
|
{
|
|
// prendo possesso della curva
|
|
PtrOwner<ICurve> pCurve( pCrv) ;
|
|
// recupero eventuale spessore del gruppo
|
|
double dThick = m_dThick ;
|
|
m_pGDB->GetInfo( nGrpId, INF_TH, dThick) ;
|
|
// se singola
|
|
if ( bSingle) {
|
|
if ( abs( dThick) > EPS_SMALL) {
|
|
pCurve->SetExtrusion( Z_AX) ;
|
|
pCurve->SetThickness( dThick) ;
|
|
}
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGrpId, Release( pCurve)) ;
|
|
return ( nId != GDB_ID_NULL && AddEntAttrib( nId, 1, nAttribId)) ;
|
|
}
|
|
// altrimenti parte dell'unica curva composita del gruppo
|
|
// se esiste già la curva composita
|
|
int nId = m_pGDB->GetFirstInGroup( nGrpId) ;
|
|
if ( nId != GDB_ID_NULL) {
|
|
ICurveComposite* pCrvCompo = GetCurveComposite( m_pGDB->GetGeoObj( nId)) ;
|
|
return ( pCrvCompo != nullptr &&
|
|
pCrvCompo->AddCurve( Release( pCurve), true, 10 * EPS_SMALL) &&
|
|
AddEntAttrib( nId, pCrvCompo->GetCurveCount(), nAttribId)) ;
|
|
}
|
|
// altrimenti la creo
|
|
PtrOwner<ICurveComposite> pNewCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pNewCompo) || ! pNewCompo->AddCurve( Release( pCurve), true, 10 * EPS_SMALL))
|
|
return false ;
|
|
if ( abs( dThick) > EPS_SMALL) {
|
|
pNewCompo->SetExtrusion( Z_AX) ;
|
|
pNewCompo->SetThickness( dThick) ;
|
|
}
|
|
int nNewId = m_pGDB->AddGeoObj( GDB_ID_NULL, nGrpId, Release( pNewCompo)) ;
|
|
return ( nNewId != GDB_ID_NULL && AddEntAttrib( nNewId, 1, nAttribId)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::AddEntAttrib( int nEntId, int nSubEntId, int nAttribId)
|
|
{
|
|
// attributo di entità non previsto
|
|
if ( nAttribId <= 0 || nAttribId > int( m_vAttrib.size()))
|
|
return true ;
|
|
// costruisco la chiave
|
|
string sKey = INF_ATTR + "_" + ToString( nSubEntId) ;
|
|
// assegno l'attributo
|
|
return m_pGDB->SetInfo( nEntId, sKey, string( m_vAttrib[ nAttribId - 1].szText)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ReadCNurbsData( int nPos, CNurbsData& cnData)
|
|
{
|
|
// verifico che il file sia aperto
|
|
if ( ! m_InEnsFile.is_open())
|
|
return false ;
|
|
|
|
// mi porto nella posizione indicata
|
|
m_InEnsFile.seekg( nPos) ;
|
|
if ( m_InEnsFile.fail())
|
|
return false ;
|
|
|
|
// leggo i dati fissi
|
|
#pragma pack( 2)
|
|
struct FixedCNurbs {
|
|
short nDeg ;
|
|
short nBaseType ;
|
|
short nExtType ;
|
|
short nParamType ;
|
|
short nCurveType ;
|
|
short nFlatCurve ;
|
|
short nIntervNbr ;
|
|
short nNodeNbr ;
|
|
short nCtrPntNbr ;
|
|
short nIntPntNbr ;
|
|
short nExtrType ;
|
|
short nCtrPntShow ;
|
|
short nQualityShow ;
|
|
double dStartPar ;
|
|
double dEndPar ;
|
|
};
|
|
const int FIXEDCNURBS_SIZE = sizeof( FixedCNurbs) ; // 42
|
|
#pragma pack()
|
|
FixedCNurbs FCN ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( &FCN), FIXEDCNURBS_SIZE) ;
|
|
if ( m_InEnsFile.gcount() != FIXEDCNURBS_SIZE)
|
|
return false ;
|
|
// assegno dati fissi
|
|
cnData.nDeg = FCN.nDeg ;
|
|
cnData.bRat = ( FCN.nBaseType == 0) ;
|
|
cnData.bPeriodic = ( FCN.nExtrType == 1) ;
|
|
cnData.bClosed = false ;
|
|
cnData.bExtraKnotes = false ;
|
|
|
|
// preparo spazio per dati variabili
|
|
cnData.vU.reserve( FCN.nNodeNbr) ;
|
|
cnData.vCP.reserve( FCN.nCtrPntNbr) ;
|
|
if ( cnData.bRat)
|
|
cnData.vW.reserve( FCN.nCtrPntNbr) ;
|
|
// leggo i nodi
|
|
for ( int i = 0 ; i < FCN.nNodeNbr ; ++ i) {
|
|
double dNode ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( &dNode), sizeof( dNode)) ;
|
|
if ( m_InEnsFile.gcount() != sizeof( dNode))
|
|
return false ;
|
|
cnData.vU.emplace_back( dNode) ;
|
|
}
|
|
// leggo i punti di controllo con eventuali pesi
|
|
for ( int i = 0 ; i < FCN.nCtrPntNbr ; ++ i) {
|
|
// leggo il punto di controllo
|
|
double dCoord[3] ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( dCoord), sizeof( dCoord)) ;
|
|
if ( m_InEnsFile.gcount() != sizeof( dCoord))
|
|
return false ;
|
|
cnData.vCP.emplace_back( ConvertToPointMM( dCoord[0], dCoord[1], dCoord[2])) ;
|
|
// se razionale leggo anche il peso
|
|
if ( cnData.bRat) {
|
|
double dWeight ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( &dWeight), sizeof( dWeight)) ;
|
|
if ( m_InEnsFile.gcount() != sizeof( dWeight))
|
|
return false ;
|
|
cnData.vW.emplace_back( ConvertToMM( dWeight)) ;
|
|
}
|
|
}
|
|
// Verifico il numero di nodi
|
|
if ( cnData.vU.size() != FCN.nNodeNbr || FCN.nNodeNbr < 2)
|
|
return false ;
|
|
// Verifico il numero di punti di controllo
|
|
if ( cnData.vCP.size() != FCN.nCtrPntNbr || FCN.nCtrPntNbr < 2)
|
|
return false ;
|
|
// Verifico il numero di pesi
|
|
if ( cnData.bRat && cnData.vW.size() != FCN.nCtrPntNbr)
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCsf::ReadExtendedTextData( int nPos, ExtendedText& etData)
|
|
{
|
|
// verifico che il file sia aperto
|
|
if ( ! m_InEnsFile.is_open())
|
|
return false ;
|
|
|
|
// mi porto nella posizione indicata
|
|
m_InEnsFile.seekg( nPos) ;
|
|
if ( m_InEnsFile.fail())
|
|
return false ;
|
|
|
|
// leggo i dati fissi
|
|
#pragma pack( 2)
|
|
struct FixedExtText {
|
|
double dH ;
|
|
double dRat ;
|
|
short nStyle ;
|
|
short nColor ;
|
|
int bItalic ;
|
|
int bUnderline ;
|
|
int bStrikeout ;
|
|
short nCharNbr ;
|
|
short nPntNbr ;
|
|
};
|
|
const int FIXEDEXTTEXT_SIZE = sizeof( FixedExtText) ; // 36
|
|
#pragma pack()
|
|
FixedExtText FET ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( &FET), FIXEDEXTTEXT_SIZE) ;
|
|
if ( m_InEnsFile.gcount() != FIXEDEXTTEXT_SIZE)
|
|
return false ;
|
|
// assegno i dati fissi
|
|
etData.dH = ConvertToMM( FET.dH) ;
|
|
etData.dRat = FET.dRat ;
|
|
etData.nWeight = FET.nStyle ;
|
|
etData.nColor = FET.nColor ;
|
|
etData.bItalic = ( FET.bItalic != 0) ;
|
|
etData.bUnderline = ( FET.bUnderline != 0) ;
|
|
etData.bStrikeout = ( FET.bStrikeout != 0) ;
|
|
|
|
// preparo spazio per dati variabili
|
|
const int FONTNAME_LEN = 31 ;
|
|
etData.sFont.reserve( FONTNAME_LEN) ;
|
|
etData.sText.reserve( FET.nCharNbr) ;
|
|
etData.vPnt.reserve( FET.nPntNbr) ;
|
|
etData.vAng.reserve( FET.nPntNbr) ;
|
|
// leggo il testo (l'ultimo carattere deve essere null)
|
|
for ( int i = 0 ; i < FET.nCharNbr ; ++ i) {
|
|
char cVal ;
|
|
m_InEnsFile.read( &cVal, 1) ;
|
|
if ( m_InEnsFile.gcount() != 1)
|
|
return false ;
|
|
if ( cVal != '\0')
|
|
etData.sText += cVal ;
|
|
}
|
|
// leggo i punti
|
|
for ( int i = 0 ; i < FET.nPntNbr ; ++ i) {
|
|
double dCoord[3] ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( dCoord), sizeof( dCoord)) ;
|
|
if ( m_InEnsFile.gcount() != sizeof( dCoord))
|
|
return false ;
|
|
etData.vPnt.emplace_back( ConvertToPointMM( dCoord[0], dCoord[1], dCoord[2])) ;
|
|
}
|
|
// leggo gli angoli
|
|
for ( int i = 0 ; i < FET.nPntNbr ; ++ i) {
|
|
double dAng ;
|
|
m_InEnsFile.read( reinterpret_cast<char*>( &dAng), sizeof( dAng)) ;
|
|
if ( m_InEnsFile.gcount() != sizeof( dAng))
|
|
return false ;
|
|
etData.vAng.emplace_back( dAng) ;
|
|
}
|
|
// leggo il font (devo salvare solo fino al primo null)
|
|
bool bSave = true ;
|
|
for ( int i = 0 ; i < FONTNAME_LEN ; ++ i) {
|
|
char cVal ;
|
|
m_InEnsFile.read( &cVal, 1) ;
|
|
if ( m_InEnsFile.gcount() != 1)
|
|
return false ;
|
|
bSave = bSave && ( cVal != '\0') ;
|
|
if ( bSave)
|
|
etData.sFont += cVal ;
|
|
}
|
|
// Verifico il numero di caratteri
|
|
if ( etData.sText.size() != FET.nCharNbr - 1)
|
|
return false ;
|
|
// Verifico il numero di punti
|
|
if ( etData.vPnt.size() != FET.nPntNbr)
|
|
return false ;
|
|
// Verifico il numero di angoli
|
|
if ( etData.vAng.size() != FET.nPntNbr)
|
|
return false ;
|
|
return true ;
|
|
}
|