Files
EgtExchange/ImportDxfBlocks.cpp
Dario Sassi a7163a4ac6 EgtExchange :
- in import BTL non c'è più errore ma solo warning se foro completamente fuori dal pezzo
- in import BTL rese più strette tolleranze approssimazione curve
- migliorate segnalazioni ora LOG_WARN, LOG_INFO e LOG_DBG_INFO.
2019-03-28 08:27:46 +00:00

318 lines
11 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : ImportDxfBlocks.cpp Data : 20.05.14 Versione : 1.5e4
// Contenuto : Implementazione di ImportDxf : gestione dei blocchi.
//
//
//
// Modifiche : 20.05.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "ImportDxf.h"
#include "DxfConst.h"
#include "DllMain.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkGdbIterator.h"
#include "/EgtDev/Include/EGnStringKeyVal.h"
using namespace std ;
//----------------------------------------------------------------------------
bool
ImportDxf::ReadBlocks( bool& bFileEnd)
{
// ciclo di lettura
bool bOk = true ;
bool bSectEnd = false ;
string sEntName ;
do {
// leggo intestazione entità, per avere il tipo
bool bOkLoc = GetEntityName( sEntName, bSectEnd, bFileEnd) ;
if ( bOkLoc && ! bSectEnd) {
// se Blocco
if ( sEntName == "BLOCK") {
if ( ! ReadBlock( bFileEnd))
bOkLoc = false ;
}
// se Fine Blocco
else if ( sEntName == "ENDBLK") {
if ( ! ReadEndBlock( bFileEnd))
bOkLoc = false ;
}
// se Entità
else if ( ReadOneEntity( sEntName, bOkLoc, bFileEnd))
;
// altrimenti ...
else {
string sOut = "ImportDxf : Skip entity " + sEntName +
" at line " + ToString( m_theScanner.GetCurrLineNbr()) ;
LOG_WARN( GetEExLogger(), sOut.c_str())
if ( ! SkipEntity( bFileEnd))
bOkLoc = false ;
}
}
// gestisco eventuale errore
if ( ! bOkLoc) {
bOk = false ;
string sOut = "ImportDxf : Error on line " + ToString( m_theScanner.GetCurrLineNbr()) ;
LOG_ERROR( GetEExLogger(), sOut.c_str())
}
} while ( ! bSectEnd) ;
// risolvo eventuali riferimenti in sospeso a blocchi
SolveBlockReferences() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadBlock( bool& bFileEnd)
{
Point3d ptP ;
string sName ;
string sLayer ;
int nFlags = 0 ;
// ciclo di lettura degli item della linea
bFileEnd = false ;
int nCode = CODE_NULL ;
do {
// leggo un Item
nCode = ReadNextItem() ;
if ( nCode == CODE_NULL) {
bFileEnd = true ;
return false ;
}
// eventuale gestione
switch ( nCode) {
case 2 :
sName = m_sCurrItem ;
break ;
case 8 :
sLayer = m_sCurrItem ;
break ;
case 10 :
FromString( m_sCurrItem, ptP.x) ;
break ;
case 20 :
FromString( m_sCurrItem, ptP.y) ;
break ;
case 30 :
FromString( m_sCurrItem, ptP.z) ;
break ;
case 70 :
FromString( m_sCurrItem, nFlags) ;
break ;
}
} while ( nCode != 0) ;
UngetItem() ;
// eventuale aggiustamento del nome per caratteri non ammessi
ValidateVal( sName) ;
// eventuale aggiustamento del nome del layer per caratteri non ammessi
ValidateVal( sLayer) ;
// aggiusto per il fattore di scala
ptP *= m_dScaleFactor ;
// inserisco il blocco nel DB geometrico
m_nIdCurrBlock = m_pGDB->AddGroup( GDB_ID_NULL, m_nIdBlocksParent, GLOB_FRM) ;
if ( m_nIdCurrBlock == GDB_ID_NULL)
return false ;
// aggiorno Map dei Blocchi
m_nmBlock.insert( NameMap::value_type( sName, m_nIdCurrBlock)) ;
// assegnazione nome
if ( ! m_pGDB->SetName( m_nIdCurrBlock, sName))
return false ;
// assegnazione layer
if ( ! sLayer.empty()) {
if ( ! m_pGDB->SetInfo( m_nIdCurrBlock, LAYER_INFO, sLayer))
return false ;
}
// assegnazione punto di inserimento
if ( ! m_pGDB->SetInfo( m_nIdCurrBlock, POINT_INFO, ptP))
return false ;
// assegnazione flags
if ( ! m_pGDB->SetInfo( m_nIdCurrBlock, FLAGS_INFO, nFlags))
return false ;
// reset numero blocchi inseriti ma non risolti nel blocco corrente
m_nNumNotBokInCurrBlock = 0 ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::ReadEndBlock( bool& bFileEnd)
{
if ( ! SkipEntity( bFileEnd))
return false ;
if ( m_nNumNotBokInCurrBlock == 0)
m_pGDB->SetInfo( m_nIdCurrBlock, BLKOK_INFO, 1) ;
m_nIdCurrBlock = GDB_ID_NULL ;
return true ;
}
//----------------------------------------------------------------------------
int
ImportDxf::GetBlockId( const string& sName)
{
// se trovo il blocco nel map, ne restituisco l'Id
NameMap::iterator Iter = m_nmBlock.find( sName) ;
if ( Iter != m_nmBlock.end())
return Iter->second ;
// altrimenti blocco non trovato
return GDB_ID_NULL ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::SolveBlockReferences( void)
{
// creo gli iteratori
PtrOwner<IGdbIterator> pIBlo( CreateGdbIterator( m_pGDB)) ;
if ( IsNull( pIBlo))
return false ;
PtrOwner<IGdbIterator> pIEnt( CreateGdbIterator( m_pGDB)) ;
if ( IsNull( pIEnt))
return false ;
// si ripete più volte, fino a completa soluzione o max iterazioni
const int MAX_ITER = 5 ;
bool bAllBok = false ;
for ( int nIter = 0 ; ! bAllBok && nIter < MAX_ITER ; ++ nIter) {
bAllBok = true ;
// ciclo sui blocchi
bool bBlo = pIBlo->GoToFirstInGroup( m_nIdBlocksParent) ;
while ( bBlo) {
// ciclo sulle entità di ogni blocco
bool bBok = true ;
bool bEnt = pIEnt->GoToFirstInGroup( *pIBlo) ;
while ( bEnt) {
// se gruppo di inserimento di altro blocco
if ( pIEnt->GetGdbType() == GDB_TY_GROUP) {
// recupero i dati
InsertData insData ;
if ( ! LoadInsertInfo( pIEnt->GetId(), insData))
return false ;
// recupero l'identificativo del blocco da inserire
int nIdIns = GetBlockId( insData.sName) ;
if ( nIdIns == GDB_ID_NULL)
return false ;
// se blocco non ancora risolto, lascio come è
if ( ! m_pGDB->ExistsInfo( nIdIns, BLKOK_INFO)) {
bBok = false ;
bAllBok = false ;
bEnt = pIEnt->GoToNext() ;
}
// altrimenti, eseguo l'inserimento
else {
if ( ! InsertBlockInBlock( pIEnt->GetId(), nIdIns, insData))
return false ;
// cancello il gruppo e passo all'oggetto successivo
bEnt = pIEnt->EraseAndGoToNext() ;
}
}
else
bEnt = pIEnt->GoToNext() ;
}
// eventuale marcatura di blocco risolto
if ( bBok)
m_pGDB->SetInfo( pIBlo->GetId(), BLKOK_INFO, 1) ;
// passo al blocco successivo
bBlo = pIBlo->GoToNext() ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::SaveInsertInfo( int nId, const InsertData& insData)
{
if ( ! m_pGDB->SetName( nId, insData.sName))
return false ;
if ( ! m_pGDB->SetInfo( nId, LAYER_INFO, insData.sLayer))
return false ;
if ( ! m_pGDB->SetInfo( nId, POINT_INFO, insData.ptP))
return false ;
if ( ! m_pGDB->SetInfo( nId, VTEXT_INFO, insData.vtExtr))
return false ;
if ( ! m_pGDB->SetInfo( nId, ROTAT_INFO, insData.dRotAngDeg))
return false ;
if ( ! m_pGDB->SetInfo( nId, SCALE_INFO, insData.vtScale))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::LoadInsertInfo( int nId, InsertData& insData)
{
if ( ! m_pGDB->GetName( nId, insData.sName))
return false ;
if ( ! m_pGDB->GetInfo( nId, LAYER_INFO, insData.sLayer))
return false ;
if ( ! m_pGDB->GetInfo( nId, POINT_INFO, insData.ptP))
return false ;
if ( ! m_pGDB->GetInfo( nId, VTEXT_INFO, insData.vtExtr))
return false ;
if ( ! m_pGDB->GetInfo( nId, ROTAT_INFO, insData.dRotAngDeg))
return false ;
if ( ! m_pGDB->GetInfo( nId, SCALE_INFO, insData.vtScale))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportDxf::InsertBlockInBlock( int nIdDest, int nIdIns, const InsertData& insData)
{
// recupero il punto base del blocco di inserimento per determinare lo spostamento
Point3d ptBase ;
m_pGDB->GetInfo( nIdIns, POINT_INFO, ptBase) ;
Vector3d vtMove = insData.ptP - ptBase ;
// calcolo il riferimento OCS
Frame3d frOCS ;
if ( ! AreSameVectorExact( insData.vtExtr, Z_AX)) {
if ( ! frOCS.Set( ORIG, insData.vtExtr))
return false ;
}
// copio tutte le entità del blocco, trasformandole opportunamente
PtrOwner<IGdbIterator> pIEnt( CreateGdbIterator( m_pGDB)) ;
if ( IsNull( pIEnt))
return false ;
bool bFound = pIEnt->GoToFirstInGroup( nIdIns) ;
while ( bFound) {
// copio l'entità geometrica
IGeoObj* pGeoS = pIEnt->GetGeoObj() ;
if ( pGeoS == nullptr) {
string sOut = "ImportDxf : Block solve error" ;
LOG_ERROR( GetEExLogger(), sOut.c_str())
bFound = pIEnt->GoToNext() ;
continue ;
}
PtrOwner<IGeoObj> pGeo( pGeoS->Clone()) ;
if ( IsNull( pGeo))
return false ;
// inserisco l'entità nel DB
int nIdE = m_pGDB->InsertGeoObj( GDB_ID_NULL, nIdDest, GDB_BEFORE, Release( pGeo)) ;
if ( nIdE == GDB_ID_NULL)
return false ;
// eseguo le opportune trasformazioni
m_pGDB->Scale( nIdE, Frame3d( ptBase), insData.vtScale.x, insData.vtScale.y, insData.vtScale.z) ;
m_pGDB->Rotate( nIdE, ptBase, Z_AX, insData.dRotAngDeg) ;
m_pGDB->Translate( nIdE, vtMove) ;
m_pGDB->GetGeoObj( nIdE)->ToGlob( frOCS) ;
// recupero il colore
if ( ! SetColorForInsert( nIdE, pIEnt->GetId(), insData.sLayer))
return false ;
// passo alla successiva
bFound = pIEnt->GoToNext() ;
}
return true ;
}