//---------------------------------------------------------------------------- // EgalTech 2015-2019 //---------------------------------------------------------------------------- // File : ToolsMgr.cpp Data : 08.07.19 Versione : 2.1g2 // Contenuto : Implementazione gestore database utensili. // // // // Modifiche : 01.06.15 DS Creazione modulo. // 21.10.15 DS Aggiunti VERSION e TOOLSIZE in HEADER (default VERSION = 1000 e TOOLSIZE = 26). // Ora VERSION = 1001 e TOOLSIZE = 29. // 02.03.17 DS Aggiunto controllo nome. // 08.07.19 DS Aggiunto water jet. Ora VERSION = 1002. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ToolsMgr.h" #include "DllMain.h" #include "MachConst.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDEv/Include/EGnFileUtils.h" #include "/EgtDEv/Include/EGnScanner.h" #include "/EgtDEv/Include/EGnWriter.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EXeExecutor.h" #include #include using namespace std ; //---------------------------------------------------------------------------- const string TF_HEADER = "[HEADER]" ; const string TF_VERSION = "VERSION" ; const string TF_TOOLSIZE = "TOOLSIZE" ; const string TF_TOTAL = "TOTAL" ; const int TF_CURR_VER = 1002 ; //---------------------------------------------------------------------------- ToolsMgr::ToolsMgr( void) { m_suCIter = m_suData.cend() ; m_bCurrTool = false ; m_bModified = false ; } //---------------------------------------------------------------------------- bool ToolsMgr::Clear( void) { // pulisco le raccolte m_suData.clear() ; m_utData.clear() ; // reinizializzo stato m_suCIter = m_suData.cend() ; m_bCurrTool = false ; m_bModified = false ; m_utModified.clear() ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::Load( const string& sToolsDir, const string& sToolsFile) { // salvo la path del file con i dati m_sToolsDir = sToolsDir ; m_sToolsPath = m_sToolsDir + "\\" + sToolsFile ; string sOut = "ToolsMgr Init : " + m_sToolsPath ; LOG_INFO( GetEMkLogger(), sOut.c_str()) // carico return Reload() ; } //---------------------------------------------------------------------------- bool ToolsMgr::Reload( void) { // pulisco Clear() ; // inizializzo lo scanner Scanner TheScanner ; if ( ! TheScanner.Init( m_sToolsPath, ";")) { LOG_ERROR( GetEMkLogger(), "ReloadTools : Error on Init") if ( ExistsDirectory( m_sToolsDir) && ! ExistsFile( m_sToolsPath)) { m_bModified = true ; return true ; } else return false ; } // variabili di stato della lettura bool bOk = true ; bool bEnd = false ; // leggo l'intestazione int nVersion = 0 ; int nToolSize = 0 ; int nTotal = 0 ; if ( ! LoadHeader( TheScanner, nVersion, nToolSize, nTotal, bEnd)) { bOk = false ; string sOut = "ReloadTools : Error on Header" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) } { string sOut = "ReloadTools : FileVer = " + ToString( nVersion) + " CurrVer = " + ToString( TF_CURR_VER) ; LOG_DBG_INFO( GetEMkLogger(), sOut.c_str()) } // dimensiono maps const int MIN_BUCKETS = 53 ; m_utData.rehash( MIN_BUCKETS) ; // ciclo di lettura degli utensili do { ToolData tData ; if ( LoadOneTool( TheScanner, nToolSize, tData, bEnd)) { if ( ! tData.m_sName.empty()) { // salvo i dati dell'utensile if ( ! m_utData.emplace( tData.m_Uuid, tData).second || ! m_suData.emplace( tData.m_sName, tData.m_Uuid).second) { bOk = false ; string sOut = "ReloadTools : Error adding tool " + tData.m_sName ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) } } } else { bOk = false ; string sOut = "ReloadTools : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) } } while ( bOk && ! bEnd) ; // termino lo scanner TheScanner.Terminate() ; // verifico di aver letto il numero di utensili indicato in header if ( m_utData.size() != nTotal) { bOk = false ; LOG_ERROR( GetEMkLogger(), "ReloadTools : Tools number wrong") } return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::LoadHeader( Scanner& TheScanner, int& nVersion, int& nToolSize, int& nTotal, bool& bEnd) const { // leggo la prossima linea string sLine ; if ( ! TheScanner.GetLine( sLine)) { // fine file bEnd = true ; return true ; } // deve essere intestazione if ( sLine != TF_HEADER) return false ; bool bOk = true ; // leggo le linee successive bEnd = true ; nVersion = 1000 ; nToolSize = 26 ; nTotal = 0 ; while ( bOk && TheScanner.GetLine( sLine)) { // se utensile successivo if ( sLine.front() == '[' && sLine.back() == ']') { TheScanner.UngetLine( sLine) ; bEnd = false ; break ; } // separo chiave da valore string sKey, sVal ; SplitFirst( sLine, "=", sKey, sVal) ; // riconosco la chiave if ( ToUpper( sKey) == TF_VERSION) bOk = FromString( sVal, nVersion) ; else if ( ToUpper( sKey) == TF_TOOLSIZE) bOk = FromString( sVal, nToolSize) ; else if ( ToUpper( sKey) == TF_TOTAL) bOk = FromString( sVal, nTotal) ; else bOk = false ; } return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::LoadOneTool( Scanner& TheScanner, int nToolSize, ToolData& tData, bool& bEnd) const { // leggo la prossima linea string sLine ; if ( ! TheScanner.GetLine( sLine)) { tData.m_sName = "" ; // fine file bEnd = true ; return true ; } // deve essere intestazione if ( sLine.front() != '[' || sLine.back() != ']') return false ; // uso temporaneamente come nome utensile tData.m_sName = sLine.substr( 1, sLine.length() - 2) ; bool bOk = ! tData.m_sName.empty() ; // dati successivi bEnd = true ; const int DIM_BS = 64 ; bitset Flag ; assert( nToolSize <= DIM_BS) ; while ( bOk && TheScanner.GetLine( sLine)) { // se utensile successivo if ( sLine.front() == '[' && sLine.back() == ']') { TheScanner.UngetLine( sLine) ; bEnd = false ; break ; } // interpreto la linea int nKey = - 1 ; bOk = tData.FromString( sLine, nKey) ; // se tutto bene, dichiaro letto il campo if ( bOk) Flag.set( nKey) ; } // verifico di aver letto tutti i campi bOk = bOk && ( Flag.count() == nToolSize) ; return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::Save( bool bCompressed) const { // se non ci sono state modifiche, esco subito if ( ! m_bModified) return true ; // faccio copia di backup del file originale CopyFileEgt( m_sToolsPath, m_sToolsPath + ".bak") ; // inizializzo il writer Writer TheWriter ; if ( ! TheWriter.Init( m_sToolsPath, bCompressed)) { LOG_ERROR( GetEMkLogger(), "SaveTools : Error on Init") return false ; } // scrivo linea di inizio file string sOut = "; --- " + m_sToolsPath + " " + CurrDateTime() + " ---" ; if ( ! TheWriter.OutText( sOut)) { LOG_ERROR( GetEMkLogger(), "SaveTools : Error on Start") return false ; } // scrivo l'intestazione if ( ! SaveHeader( TheWriter)) { LOG_ERROR( GetEMkLogger(), "SaveTools : Error on Header") return false ; } // ciclo su tutti i nomi degli utensili int nCounter = 0 ; for ( auto iIter = m_suData.cbegin() ; iIter != m_suData.cend() ; ++ iIter) { // salvo l'utensile if ( ! SaveOneTool( iIter->second, nCounter, TheWriter)) { string sOut = "SaveTools : Error on tool " + iIter->first ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) return false ; } } // scrivo linea di fine file if ( ! TheWriter.OutText( "; --- End ---")) { LOG_ERROR( GetEMkLogger(), "SaveTools : Error on End") return false ; } // chiudo la scrittura TheWriter.Close() ; // dichiaro non più modificato rispetto al file m_bModified = false ; m_utModified.clear() ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::SaveHeader( Writer& TheWriter) const { // scrivo l'intestazione bool bOk = true ; string sOut ; sOut = TF_HEADER ; bOk = bOk && TheWriter.OutText( sOut) ; sOut = TF_VERSION + "=" + ToString( TF_CURR_VER) ; bOk = bOk && TheWriter.OutText( sOut) ; sOut = TF_TOOLSIZE + "=" + ToString( ToolData::GetSize()) ; bOk = bOk && TheWriter.OutText( sOut) ; sOut = TF_TOTAL + "=" + ToString( int( m_utData.size())) ; bOk = bOk && TheWriter.OutText( sOut) ; return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::SaveOneTool( const EgtUUID& Uuid, int& nCounter, Writer& TheWriter) const { // recupero i dati dell'utensile auto iIter = m_utData.find( Uuid) ; if ( iIter == m_utData.end()) return false ; const ToolData& tData = iIter->second ; // scrivo i dati dell'utensile string sOut = "[TOOL_" + ToString( ++ nCounter, 3) + "]" ; bool bOk = TheWriter.OutText( sOut) ; for ( int i = 0 ; i < tData.GetSize() ; ++ i) { string sOut = tData.ToString( i) ; bOk = bOk && ! sOut.empty() && TheWriter.OutText( sOut) ; } return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetToolNewName( string& sName) const { // il parametro nome deve essere valido if ( &sName == nullptr) return false ; // se nome vuoto, assegno radice standard if ( sName.empty()) sName = "Tool" ; // verifico che il nome sia unico int nCount = 0 ; string sOrigName = sName ; if ( sOrigName.length() > 2 && sOrigName.rfind( "_1") == sOrigName.length() - 2) sOrigName.erase( sOrigName.length() - 2) ; while ( GetTool( sName) != nullptr) { ++ nCount ; sName = sOrigName + "_" + ToString( nCount) ; } return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::AddTool( const string& sName, int nType) { // annullo utensile corrente m_bCurrTool = false ; // verifico validità del nome if ( ! IsValidVal( sName)) return false ; // verifico unicità del nome if ( m_suData.find( sName) != m_suData.end()) return false ; // verifico validità del tipo if ( ! IsValidToolType( nType)) return false ; // definisco un utensile con valori di default ToolData tData ; tData.m_sName = sName ; tData.m_nType = nType ; CreateEgtUUID( tData.m_Uuid) ; // salvo i dati dell'utensile if ( ! m_utData.emplace( tData.m_Uuid, tData).second || ! m_suData.emplace( tData.m_sName, tData.m_Uuid).second) return false ; m_bModified = true ; if ( find( m_utModified.begin(), m_utModified.end(), tData.m_Uuid) == m_utModified.end()) m_utModified.emplace_back( tData.m_Uuid) ; // lo rendo il nuovo utensile corrente m_bCurrTool = true ; m_tdCurrTool = tData ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::CopyTool( const string& sSource, const string& sName) { // annullo utensile corrente m_bCurrTool = false ; // verifico validità del nome if ( ! IsValidVal( sName)) return false ; // verifico unicità del nome if ( m_suData.find( sName) != m_suData.end()) return false ; // recupero l'utensile sorgente const ToolData* pTdata = GetTool( sSource) ; if ( pTdata == nullptr) return false ; // ne faccio una copia ToolData tData = *pTdata ; // modifico nome e UUID tData.m_sName = sName ; CreateEgtUUID( tData.m_Uuid) ; // lo disattivo tData.SetParam( TPA_ACTIVE, false) ; // salvo i dati del nuovo utensile if ( ! m_utData.emplace( tData.m_Uuid, tData).second || ! m_suData.emplace( tData.m_sName, tData.m_Uuid).second) return false ; m_bModified = true ; if ( find( m_utModified.begin(), m_utModified.end(), tData.m_Uuid) == m_utModified.end()) m_utModified.emplace_back( tData.m_Uuid) ; // lo rendo il nuovo utensile corrente m_bCurrTool = true ; m_tdCurrTool = tData ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::RemoveTool( const string& sName) { // cerco l'utensile nell'elenco dei nomi auto iNameIter = m_suData.find( sName) ; if ( iNameIter == m_suData.end()) return true ; EgtUUID ToolUuid = iNameIter->second ; // se era anche l'utensile corrente, lo resetto if ( m_bCurrTool && m_tdCurrTool.m_Uuid == ToolUuid) m_bCurrTool = false ; // rimuovo l'utensile dal dizionario degli UUID m_utData.erase( ToolUuid) ; // rimuovo l'utensile dall'elenco dei nomi m_suData.erase( iNameIter) ; // dichiaro la modifica m_bModified = true ; if ( find( m_utModified.begin(), m_utModified.end(), ToolUuid) == m_utModified.end()) m_utModified.emplace_back( ToolUuid) ; return true ; } //---------------------------------------------------------------------------- const ToolData* ToolsMgr::GetTool( const EgtUUID& Uuid) const { auto iIter = m_utData.find( Uuid) ; if ( iIter == m_utData.end()) return nullptr ; return &( iIter->second) ; } //---------------------------------------------------------------------------- const ToolData* ToolsMgr::GetTool( const string& sName) const { auto iIter = m_suData.find( sName) ; if ( iIter == m_suData.end()) return nullptr ; return GetTool( iIter->second) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetFirstTool( int nFamily, string& sName, int& nType) const { // primo nome m_suCIter = m_suData.begin() ; // lo verifico if ( VerifyTool( nFamily, sName, nType)) return true ; // continuo ricerca return GetNextTool( nFamily, sName, nType) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetNextTool( int nFamily, string& sName, int& nType) const { // mentre esiste utensile while ( m_suCIter != m_suData.end()) { // nome successivo ++ m_suCIter ; // lo verifico if ( VerifyTool( nFamily, sName, nType)) return true ; } // non trovato return false ; } //---------------------------------------------------------------------------- bool ToolsMgr::VerifyTool( int nFamily, string& sName, int& nType) const { // il corrente deve esistere if ( m_suCIter == m_suData.end()) return false ; // relativo utensile auto iIter = m_utData.find( m_suCIter->second) ; if ( iIter == m_utData.end()) { m_suCIter = m_suData.end() ; return false ; } // se appartiene alla famiglia richiesta, trovato if ( ( iIter->second.m_nType & nFamily) != 0) { sName = iIter->second.m_sName ; nType = iIter->second.m_nType ; return true ; } return false ; } //---------------------------------------------------------------------------- bool ToolsMgr::SetCurrTool( const string& sName) { // se nome vuoto, faccio reset if ( sName.empty()) { m_bCurrTool = false ; return false ; } // recupero i dati dell'utensile const ToolData* ptData = GetTool( sName) ; if ( ptData == nullptr) { m_bCurrTool = false ; return false ; } // li salvo come correnti m_bCurrTool = true ; m_tdCurrTool = *ptData ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::SaveCurrTool( void) { // verifico validità utensile corrente if ( ! m_bCurrTool) return false ; // recupero puntatore a utensile corrente nel DB auto iIter = m_utData.find( m_tdCurrTool.m_Uuid) ; if ( iIter == m_utData.end()) return false ; // se cambiato nome, devo aggiornare tabella relativa if ( m_tdCurrTool.m_sName != iIter->second.m_sName) { // cerco l'utensile nell'elenco dei nomi auto iNameIter = m_suData.find( iIter->second.m_sName) ; if ( iNameIter != m_suData.end()) { // rimuovo vecchio nome m_suData.erase( iNameIter) ; // inserisco nuovo m_suData.emplace( m_tdCurrTool.m_sName, m_tdCurrTool.m_Uuid) ; } } // se fresa adatto sottotipo a seconda della capacità di lavorare di testa if ( m_tdCurrTool.m_nType == TT_MILL_STD && m_tdCurrTool.m_dTipFeed < EPS_SMALL) m_tdCurrTool.m_nType = TT_MILL_NOTIP ; else if ( m_tdCurrTool.m_nType == TT_MILL_NOTIP && m_tdCurrTool.m_dTipFeed > EPS_SMALL) m_tdCurrTool.m_nType = TT_MILL_STD ; // eseguo salvataggio m_bModified = true ; if ( find( m_utModified.begin(), m_utModified.end(), m_tdCurrTool.m_Uuid) == m_utModified.end()) m_utModified.emplace_back( m_tdCurrTool.m_Uuid) ; iIter->second = m_tdCurrTool ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::UpdateCurrToolHolderData( double dTHoldBase, double dTHoldLen, double dTHoldDiam) { // verifico validità utensile corrente if ( ! m_bCurrTool) return false ; // Aggiorno i dati nelle note di sistema SetValInNotes( TSI_THBASE, dTHoldBase, m_tdCurrTool.m_sSysNotes) ; SetValInNotes( TSI_THLEN, dTHoldLen, m_tdCurrTool.m_sSysNotes) ; SetValInNotes( TSI_THDIAM, dTHoldDiam, m_tdCurrTool.m_sSysNotes) ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::IsCurrToolModified( void) const { // verifico validità utensile corrente if ( ! m_bCurrTool) return false ; // recupero puntatore a utensile corrente nel DB auto iIter = m_utData.find( m_tdCurrTool.m_Uuid) ; if ( iIter == m_utData.end()) return false ; // eseguo confronto return ( ! SameTool( m_tdCurrTool, iIter->second)) ; } //---------------------------------------------------------------------------- bool ToolsMgr::SetCurrToolParam( int nType, bool bVal) { return ( m_bCurrTool ? m_tdCurrTool.SetParam( nType, bVal) : false) ; } //---------------------------------------------------------------------------- bool ToolsMgr::SetCurrToolParam( int nType, int nVal) { return ( m_bCurrTool ? m_tdCurrTool.SetParam( nType, nVal) : false) ; } //---------------------------------------------------------------------------- bool ToolsMgr::SetCurrToolParam( int nType, double dVal) { return ( m_bCurrTool ? m_tdCurrTool.SetParam( nType, dVal) : false) ; } //---------------------------------------------------------------------------- bool ToolsMgr::SetCurrToolParam( int nType, const string& sVal) { // deve esistere utensile corrente if ( ! m_bCurrTool) return false ; // non è possibile cambiare UUID if ( nType == TPA_UUID) return false ; // è possibile cambiare il nome, solo se il nuovo è valido e non è già presente nel DB (escluso utensile corrente) if ( nType == TPA_NAME) { if ( ! IsValidVal( sVal)) return false ; const ToolData* pTdata = GetTool( sVal) ; if ( pTdata != nullptr && pTdata->m_Uuid != m_tdCurrTool.m_Uuid) return false ; } // eseguo return m_tdCurrTool.SetParam( nType, sVal) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetCurrToolParam( int nType, bool& bVal) const { return ( m_bCurrTool ? m_tdCurrTool.GetParam( nType, bVal) : false) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetCurrToolParam( int nType, int& nVal) const { return ( m_bCurrTool ? m_tdCurrTool.GetParam( nType, nVal) : false) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetCurrToolParam( int nType, double& dVal) const { return ( m_bCurrTool ? m_tdCurrTool.GetParam( nType, dVal) : false) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetCurrToolParam( int nType, string& sVal) const { return ( m_bCurrTool ? m_tdCurrTool.GetParam( nType, sVal) : false) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetCurrToolMaxDepth( double dSafe, double& dMaxDepth) const { // verifico esistenza utensile corrente if ( ! m_bCurrTool) return false ; // se punta a forare if ( ( m_tdCurrTool.m_nType & TF_DRILLBIT) != 0) { dMaxDepth = m_tdCurrTool.m_dMaxMat ; return true ; } // se lama else if ( ( m_tdCurrTool.m_nType & TF_SAWBLADE) != 0) { dMaxDepth = m_tdCurrTool.m_dMaxMat ; return true ; } // se fresa else if ( ( m_tdCurrTool.m_nType & TF_MILL) != 0) { // recupero le dimensioni del porta utensili double dTHoldBase = 0 ; double dTHoldLen = 0 ; double dTHoldDiam = 0 ; bool bBaseOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ; bool bLenOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ; bool bDiamOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ; if ( ! bBaseOk || ! bLenOk || ! bDiamOk) { (const_cast(this))->UpdateCurrToolHolderData( dTHoldBase, dTHoldLen, dTHoldDiam) ; (const_cast(this))->SaveCurrTool() ; Save() ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ; } // calcolo il massimo affondamento per le limitazioni dal portautensili dMaxDepth = m_tdCurrTool.m_dLen - dSafe ; if ( dTHoldDiam > m_tdCurrTool.m_dDiam + EPS_SMALL) dMaxDepth -= dTHoldLen ; else dMaxDepth -= dTHoldBase ; // recupero l'eventuale diametro gambo utensile (definito se non nullo) double dStemDiam ; m_tdCurrTool.GetParam( TPA_STEMDIAM, dStemDiam) ; if ( dStemDiam > m_tdCurrTool.m_dDiam + EPS_SMALL) dMaxDepth = min( dMaxDepth, m_tdCurrTool.m_dMaxMat) ; return true ; } // se mortasatrice o sega a catena else if ( ( m_tdCurrTool.m_nType & TF_MORTISE) != 0) { dMaxDepth = m_tdCurrTool.m_dMaxMat ; return true ; } // se scalpello else if ( ( m_tdCurrTool.m_nType & TF_CHISEL) != 0) { dMaxDepth = m_tdCurrTool.m_dMaxMat ; return true ; } // se utensile waterjet else if ( ( m_tdCurrTool.m_nType & TF_WATERJET) != 0) { dMaxDepth = m_tdCurrTool.m_dMaxMat ; return true ; } // se utensile composito else if ( ( m_tdCurrTool.m_nType & TF_COMPO) != 0) { // non ancora gestito return false ; } return false ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetCurrToolThDiam( double& dThDiam) const { // verifico esistenza utensile corrente if ( ! m_bCurrTool) return false ; // se punta a forare, lama, fresa, mortasatrice/sega a catena o scalpello if ( ( m_tdCurrTool.m_nType & TF_DRILLBIT) != 0 || ( m_tdCurrTool.m_nType & TF_SAWBLADE) != 0 || ( m_tdCurrTool.m_nType & TF_MILL) != 0 || ( m_tdCurrTool.m_nType & TF_MORTISE) != 0 || ( m_tdCurrTool.m_nType & TF_CHISEL) != 0) { // recupero le dimensioni del porta utensili double dTHoldBase = 0 ; double dTHoldLen = 0 ; double dTHoldDiam = 0 ; bool bBaseOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ; bool bLenOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ; bool bDiamOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ; if ( ! bBaseOk || ! bLenOk || ! bDiamOk) { (const_cast(this))->UpdateCurrToolHolderData( dTHoldBase, dTHoldLen, dTHoldDiam) ; (const_cast(this))->SaveCurrTool() ; Save() ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ; } dThDiam = dTHoldDiam ; return true ; } // se waterjet else if ( ( m_tdCurrTool.m_nType & TF_WATERJET) != 0) { dThDiam = 0 ; return true ; } return false ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetCurrToolThLength( double& dThLen) const { // verifico esistenza utensile corrente if ( ! m_bCurrTool) return false ; // se punta a forare, lama, fresa, mortasatrice/sega a catena o scalpello if ( ( m_tdCurrTool.m_nType & TF_DRILLBIT) != 0 || ( m_tdCurrTool.m_nType & TF_SAWBLADE) != 0 || ( m_tdCurrTool.m_nType & TF_MILL) != 0 || ( m_tdCurrTool.m_nType & TF_MORTISE) != 0 || ( m_tdCurrTool.m_nType & TF_CHISEL) != 0) { // recupero le dimensioni del porta utensili double dTHoldBase = 0 ; double dTHoldLen = 0 ; double dTHoldDiam = 0 ; bool bBaseOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ; bool bLenOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ; bool bDiamOk = GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ; if ( ! bBaseOk || ! bLenOk || ! bDiamOk) { (const_cast(this))->UpdateCurrToolHolderData( dTHoldBase, dTHoldLen, dTHoldDiam) ; (const_cast(this))->SaveCurrTool() ; Save() ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THBASE, dTHoldBase) ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ; } dThLen = dTHoldLen ; return true ; } // se waterjet else if ( ( m_tdCurrTool.m_nType & TF_WATERJET) != 0) { dThLen = 0 ; return true ; } return false ; } //---------------------------------------------------------------------------- bool ToolsMgr::Export( const STRVECTOR& vsToolsNames, const string& sOutFile, bool bCompressed) const { LOG_INFO( GetEMkLogger(), ( "Export Tools " + sOutFile).c_str()) ; // Out Directory size_t pos = sOutFile.rfind( "\\") ; if ( pos == string::npos) return false ; string sOutDir = sOutFile.substr( 0, pos) ; // Conto i tools da esportare int nTools = 0 ; for ( STRVECTOR::const_iterator it = vsToolsNames.begin() ; it != vsToolsNames.end() ; it ++) { if ( m_suData.find( *it) != m_suData.end()) nTools ++ ; } // inizializzo il writer Writer TheWriter ; if ( ! TheWriter.Init( sOutFile, bCompressed)) { LOG_ERROR( GetEMkLogger(), "Export Tools : Error on Init") ; return false ; } // scrivo linea di inizio file string sOut = "; --- " + sOutFile + " " + CurrDateTime() + " ---" ; if ( ! TheWriter.OutText( sOut)) { LOG_ERROR( GetEMkLogger(), "Export Tools : Error on Start") ; return false ; } // scrivo l'intestazione bool bOk = TheWriter.OutText( TF_HEADER) ; bOk = bOk && TheWriter.OutText( TF_VERSION + "=" + ToString( TF_CURR_VER)) ; bOk = bOk && TheWriter.OutText( TF_TOOLSIZE + "=" + ToString( ToolData::GetSize())) ; bOk = bOk && TheWriter.OutText( TF_TOTAL + "=" + ToString( nTools)) ; if ( ! bOk) { LOG_ERROR( GetEMkLogger(), "Export Tools : Error on Header") ; return false ; } // ciclo su tutti i nomi degli utensili da esportare int nCounter = 1 ; for ( size_t i = 0 ; i < vsToolsNames.size() ; i++) { if ( ! ExportOneTool( vsToolsNames[i], TheWriter, nCounter, sOutDir)) return false ; nCounter ++ ; } // scrivo linea di fine file if ( ! TheWriter.OutText( "; --- End ---")) { LOG_ERROR( GetEMkLogger(), "Export Tools : Error on End") ; return false ; } // chiudo la scrittura TheWriter.Close() ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::ExportOneTool( const string& sToolName, Writer& TheWriter, int nCounter, const string& sOutDir) const { // se il tool non esiste nel DB lo ignoro if ( m_suData.find( sToolName) == m_suData.end()) { string sOut = "Warning Export Tool : " + sToolName + " not found. Tool is ignored" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; return true ; } const ToolData * tData = GetTool( sToolName) ; string sOut ; if ( tData == nullptr) { sOut = "Export Tools : Error exporting " + sToolName ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; return false ; } // Tool draw string sDraw = m_sToolsDir + "\\" + tData->m_sDraw ; string sOutDraw = sOutDir + "\\" + tData->m_sDraw ; if ( ! CopyToolDraw( sDraw, sOutDraw, sToolName)) return false ; // Scrittura del file sOut = "[TOOL_" + ToString( nCounter, 3) + "]" ; bool bOk = TheWriter.OutText( sOut) ; for ( int i = 0 ; bOk && i < tData->GetSize() ; ++ i) { sOut = tData->ToString( i) ; bOk = ! sOut.empty() && TheWriter.OutText( sOut) ; } if ( ! bOk) { sOut = "Export Tools : Error exporting " + sToolName ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; // visto che non ho salvato correttamente il tool elimino il suo disegno EraseFile( sOutDraw) ; return false ; } return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::ToBeImported( const string& sFile, STRVECTOR& vsToolsNames, INTVECTOR& vToolsTypes) const { Scanner TheScanner ; if ( ! TheScanner.Init( sFile, ";")) { LOG_ERROR( GetEMkLogger(), "Tools ToBeImported : Error on Init") ; return false ; } // leggo l'intestazione int nVersion = 0 ; int nToolSize = 0 ; int nTotal = 0 ; bool bEnd = false ; if ( ! LoadHeader( TheScanner, nVersion, nToolSize, nTotal, bEnd)) { LOG_ERROR( GetEMkLogger(), "Tools ToBeImported : Error on Header") ; } string sLine ; if ( ! TheScanner.GetLine( sLine)) return false ; if ( sLine.front() != '[' || sLine.back() != ']') return false ; bool bToolName = false ; bool bToolType = false ; bool bAdd = true ; string sName, sType ; while ( TheScanner.GetLine( sLine)) { if ( sLine.front() == '[' && sLine.back() == ']') { // se è intestazione // aggiungo tool precedente se ok if ( bAdd && bToolType && bToolName && IsValidToolType( stoi( sType))) { vsToolsNames.push_back( sName) ; vToolsTypes.push_back( stoi( sType)) ; } bToolName = false ; bToolType = false ; bAdd = true ; } else { string sKey, sVal ; SplitFirst( sLine, "=", sKey, sVal) ; if ( ToUpper( sKey) == "TYP") { if ( ! bToolType) { bToolType = true ; sType = sVal ; } else // se tool ha più types è errore, non potrà essere importato bAdd = false ; } if ( ToUpper( sKey) == "NAME") { if ( ! bToolName){ bToolName = true ; sName = sVal ; } else // se tool ha più nomi è errore, non potrà essere importato bAdd = false ; } } } // aggiungo ultimo tool se ok if ( bAdd && bToolType && bToolName) { vsToolsNames.push_back( sName) ; vToolsTypes.push_back( stoi( sType)) ; } if ( vsToolsNames.size() != vToolsTypes.size()) return false ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::Import( const string& sFile, const STRVECTOR& vsToolsToImport, const STRVECTOR& vsToolsNames, STRVECTOR& vsImported) { LOG_INFO( GetEMkLogger(), ( "Import Tools : " + sFile).c_str()) ; for ( size_t i = 0 ; i < vsToolsNames.size() ; i ++) { // Se esiste già nel DB un utensile con lo stesso nome lo rimuovo if ( m_suData.find( vsToolsNames[i]) != m_suData.end()) { bool bOk = RemoveTool( vsToolsNames[i]) ; if ( ! bOk){ LOG_ERROR( GetEMkLogger(), ( " Error removing " + vsToolsNames[i]).c_str()) ; return false ; } } // Verifico che il nome non sia ripetuto nella lista dei vsToolsNames if ( i != vsToolsNames.size() - 1 && find( vsToolsNames.begin() + i + 1, vsToolsNames.end(), vsToolsNames[i]) != vsToolsNames.end()) { LOG_ERROR( GetEMkLogger(), ( " Error : name \"" + vsToolsNames[i] + "\" is already used").c_str()) ; return false ; } } // File directory size_t pos = sFile.rfind( "\\") ; if ( pos == string::npos) return false ; string sFileDir = sFile.substr( 0, pos) ; // Inizializzo lo scanner Scanner TheScanner ; if ( ! TheScanner.Init( sFile, ";")) { LOG_ERROR( GetEMkLogger(), " Import Tools : Error on Init") ; return false ; } // leggo l'intestazione int nVersion = 0 ; int nToolSize = 0 ; int nTotal = 0 ; bool bEnd ; bool bOk = true ; if ( ! LoadHeader( TheScanner, nVersion, nToolSize, nTotal, bEnd)) { bOk = false ; LOG_ERROR( GetEMkLogger(), " Import Tools : Error on Header") ; } // leggo i tool string sLine ; if ( ! TheScanner.GetLine( sLine)) return false ; if ( sLine.front() != '[' || sLine.back() != ']') return false ; TheScanner.UngetLine( sLine) ; while ( TheScanner.GetLine( sLine)) { if ( sLine.front() == '[' && sLine.back() == ']') { // nuovo tool TheScanner.UngetLine( sLine) ; ToolData tData ; bOk = ReadTool( TheScanner, tData, nToolSize) ; vector::const_iterator it = find( vsToolsToImport.begin(), vsToolsToImport.end(), tData.m_sName) ; // Se il tool non deve essere importato proseguo con il successivo if ( it == vsToolsToImport.end()) continue ; // Se errore nel leggere il tool, proseguo con il successivo if ( ! bOk) { string sOut = " Error : " + vsToolsNames[ it - vsToolsToImport.begin()] + " could not be imported" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; continue ; } // Assegno il nuovo nome tData.m_sName = vsToolsNames[ it - vsToolsToImport.begin()] ; string sDraw = sFileDir + "\\" + tData.m_sDraw ; // Se il suo UUID esiste già nel DB lo modifico if ( m_utData.find( tData.m_Uuid) != m_utData.end()) { LOG_ERROR( GetEMkLogger(), ( " Warning : " + tData.m_sName + " UUID changed").c_str()) ; CreateEgtUUID( tData.m_Uuid) ; // se il nome del disegno è legato all'UUID, devo aggiornarlo con il nuovo valore if ( IsUUID( GetFileTitleEgt( sDraw))) tData.m_sDraw = ToString( tData.m_Uuid) + ".nge" ; } // Setto active = false come default per il tool importato tData.SetParam( TPA_ACTIVE, false) ; // Aggiungo il tool bOk = m_utData.emplace( tData.m_Uuid, tData).second ; bOk = bOk && m_suData.emplace( tData.m_sName, tData.m_Uuid).second ; if ( ! bOk){ LOG_ERROR( GetEMkLogger(), ( " Error adding " + tData.m_sName).c_str()) ; continue ; } string sOutDraw = m_sToolsDir + "\\" + tData.m_sDraw ; // se fallisco nel copiare il draw elimino il tool dal DB if ( ! CopyToolDraw( sDraw, sOutDraw, tData.m_sName)) { m_utData.erase( tData.m_Uuid) ; m_suData.erase( tData.m_sName) ; } else vsImported.push_back( tData.m_sName) ; } } if ( ! vsImported.empty()) m_bModified = true ; return true ; } //-------------------------------------------------------------------------- bool ToolsMgr::ReadTool( Scanner& TheScanner, ToolData& tData, int nToolSize) const { string sLine ; TheScanner.GetLine( sLine) ; // deve essere intestazione if ( sLine.front() != '[' || sLine.back() != ']') return false ; // uso temporaneamente come nome utensile tData.m_sName = sLine.substr( 1, sLine.length() - 2) ; bool bOk = ! tData.m_sName.empty() ; // dati successivi const int DIM_BS = 64 ; bitset Flag ; assert( nToolSize <= DIM_BS) ; while ( bOk && TheScanner.GetLine( sLine)) { // se utensile successivo if ( sLine.front() == '[' && sLine.back() == ']') { TheScanner.UngetLine( sLine) ; break ; } // interpreto la linea int nKey = - 1 ; bOk = tData.FromString( sLine, nKey) ; // se tutto bene, dichiaro letto il campo if ( bOk) Flag.set( nKey) ; } // verifico di aver letto tutti i campi bOk = bOk && ( Flag.count() == nToolSize) ; return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::CopyToolDraw( const string& sDraw, const string& sOutDraw, const string& sToolName) const { // se il file del disegno esiste lo copio nella nuova cartella if ( ExistsFile( sDraw)) { if ( ! CopyFileEgt( sDraw, sOutDraw)) { string sOut = " Error in copying " + sToolName + " draw" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; return false ; } return true ; } // se il file non esiste e non è standard restituisco errore if ( ! IsUUID( GetFileTitleEgt( sDraw))) { string sOut = " Error : " + sToolName + " draw not found" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; return false ; } // altrimenti il file non esiste ma è standard lo ricreo // recupero indice contesto corrente e creo nuovo contesto per disegno utensile int nGenCtx = ExeGetCurrentContext() ; int nToolCtx = ExeInitContext() ; // salvo dati utensile corrente bool bCurrToolOld = m_bCurrTool ; ToolData tdCurrToolOld = m_tdCurrTool ; // imposto utensile da esportare come corrente bool bOk = true ; if ( bOk && ! const_cast(this)->SetCurrTool( sToolName)) { string sOut = " Error in " + sToolName + " draw" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; bOk = false ; } if ( bOk && ExeTdbCurrToolDraw( nGenCtx, nToolCtx) != 0) { string sOut = " Error : " + sToolName + " CurrToolDraw" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; bOk = false ; } if ( bOk && ! ExeSaveFile( sOutDraw, GDB_SV_CMPTXT)) { string sOut = " Error : saving " + sToolName + " tool draw" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; bOk = false ; } // ripristino utensile corrente const_cast(this)->m_bCurrTool = bCurrToolOld ; const_cast(this)->m_tdCurrTool = tdCurrToolOld ; // ripristino contesto corrente e cancello quello creato ad hoc ExeSetCurrentContext( nGenCtx) ; ExeDeleteContext( nToolCtx) ; return bOk ; }