//---------------------------------------------------------------------------- // 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/EmkToolConst.h" #include "/EgtDEv/Include/EGnStringKeyVal.h" #include "/EgtDEv/Include/EGnFileUtils.h" #include "/EgtDEv/Include/EGnScanner.h" #include "/EgtDEv/Include/EGnWriter.h" #include "/EgtDev/Include/EgtPointerOwner.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") 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 { if ( ! LoadOneTool( TheScanner, nToolSize, bEnd)) { 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) { // 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, bool& bEnd) { ToolData tData ; // leggo la prossima linea string sLine ; if ( ! TheScanner.GetLine( sLine)) { // 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) ; // salvo i dati dell'utensile bOk = bOk && m_utData.emplace( tData.m_Uuid, tData).second ; bOk = bOk && m_suData.emplace( tData.m_sName, tData.m_Uuid).second ; 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) ; } } // aggiorno dati portautensile UpdateCurrToolHolderData() ; // 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( void) { // Leggo i dati del portautensile dal disegno dell'utensile PtrOwner pGeomDB( CreateGeomDB()) ; pGeomDB->Init() ; string sDrawPath = m_sToolsDir + "\\" + m_tdCurrTool.m_sDraw ; pGeomDB->Load( sDrawPath) ; int nToolId = pGeomDB->GetFirstGroupInGroup( GDB_ID_ROOT) ; double dTHoldLen = 0 ; pGeomDB->GetInfo( nToolId, TTH_LEN, dTHoldLen) ; double dTHoldDiam = 0 ; pGeomDB->GetInfo( nToolId, TTH_DIAM, dTHoldDiam) ; // Aggiorno i dati nelle note di sistema 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 dTHoldLen = 0 ; double dTHoldDiam = 0 ; if ( ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) || ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam)) { (const_cast(this))->SaveCurrTool() ; Save() ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ; } // calcolo il massimo affondamento dMaxDepth = m_tdCurrTool.m_dLen - ( m_tdCurrTool.m_dDiam > dTHoldDiam ? 0 : dTHoldLen) - dSafe ; 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 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_CHISEL) != 0) { // recupero le dimensioni del porta utensili double dTHoldLen = 0 ; double dTHoldDiam = 0 ; if ( ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) || ! GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam)) { (const_cast(this))->SaveCurrTool() ; Save() ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THLEN, dTHoldLen) ; GetValInNotes( m_tdCurrTool.m_sSysNotes, TSI_THDIAM, dTHoldDiam) ; } dThDiam = dTHoldDiam ; return true ; } // se mortasatrice/sega a catena o waterjet else if ( ( m_tdCurrTool.m_nType & TF_MORTISE) != 0 || ( m_tdCurrTool.m_nType & TF_WATERJET) != 0) { dThDiam = 0 ; return true ; } return false ; }