a7163a4ac6
- 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.
318 lines
11 KiB
C++
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 ;
|
|
} |