//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : Machine.cpp Data : 06.05.15 Versione : 1.6e3 // Contenuto : Implementazione gestione macchina. // // // // Modifiche : 06.05.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "MachMgr.h" #include "DllMain.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkGeoVector3d.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EGnFileUtils.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- Machine::Machine( void) { m_pMchMgr = nullptr ; m_nGroupId = GDB_ID_NULL ; } //---------------------------------------------------------------------------- Machine::~Machine( void) { Clear() ; } //---------------------------------------------------------------------------- void Machine::Clear( void) { // cancellazione eventuali gruppi geometrici associati if ( m_pMchMgr != nullptr && m_pMchMgr->m_pGeomDB != nullptr) { if ( m_nGroupId != GDB_ID_NULL) m_pMchMgr->m_pGeomDB->Erase( m_nGroupId) ; if ( m_nTempGroupId != GDB_ID_NULL) m_pMchMgr->m_pGeomDB->Erase( m_nTempGroupId) ; } // pulizia interprete lua di macchina LuaExit() ; // reset membri m_pMchMgr = nullptr ; m_sName.clear() ; m_sMachineDir.clear() ; m_nGroupId = GDB_ID_NULL ; m_nTempGroupId = GDB_ID_NULL ; m_mapGroups.clear() ; m_mapGroups.rehash( 20) ; } //---------------------------------------------------------------------------- bool Machine::Init( const std::string& sMachineName, MachMgr* pMchMgr) { // pulisco Clear() ; // verifico ambiente if ( pMchMgr == nullptr || pMchMgr->m_nContextId == 0 || pMchMgr->m_pGeomDB == nullptr) return false ; m_pMchMgr = pMchMgr ; // verifico direttorio dati macchina m_sMachineDir = pMchMgr->m_sMachinesDir + "\\" + sMachineName ; if ( ! ExistsDirectory( m_sMachineDir)) return false ; // creo il gruppo per la macchina int nId = pMchMgr->m_pGeomDB->InsertGroup( GDB_ID_NULL, pMchMgr->m_nMachAuxId, GDB_LAST_SON, GLOB_FRM) ; if ( nId == GDB_ID_NULL) return false ; // imposto nome del gruppo pMchMgr->m_pGeomDB->SetName( nId, sMachineName) ; // carico l'interprete lua dedicato alla macchina if ( ! LuaInit( sMachineName)) { pMchMgr->m_pGeomDB->Erase( nId) ; return false ; } // salvo i dati m_nGroupId = nId ; m_sName = sMachineName ; // carico la macchina { string sMachineMde = m_sMachineDir + "\\" + sMachineName + ".Mde" ; bool bOk = LuaExecFile( sMachineMde) ; // cancello il gruppo temporaneo pMchMgr->m_pGeomDB->Erase( m_nTempGroupId) ; m_nTempGroupId = GDB_ID_NULL ; // in caso di errore, cancello tutta la geometria if ( ! bOk) { pMchMgr->m_pGeomDB->Erase( m_nGroupId) ; pMchMgr->m_pGeomDB->Erase( m_nTempGroupId) ; m_nGroupId = GDB_ID_NULL ; m_nTempGroupId = GDB_ID_NULL ; m_sName.clear() ; m_sMachineDir.clear() ; } return bOk ; } //---------------------------------------------------------------------------- bool Machine::LoadMachineGeometry( const string& sMGeoName, const Vector3d& vtOffset) { // creo un sotto gruppo temporaneo in cui caricare la macchina m_nTempGroupId = m_pMchMgr->m_pGeomDB->AddGroup( GDB_ID_NULL, m_pMchMgr->m_nMachAuxId, GLOB_FRM) ; if ( m_nTempGroupId == GDB_ID_NULL) return false ; // carico la macchina string sMachineNge = m_sMachineDir + "\\" + sMGeoName ; if ( ! m_pMchMgr->m_pGeomDB->Load( sMachineNge, m_nTempGroupId)) return false ; // applico offset return m_pMchMgr->m_pGeomDB->TranslateGlob( m_nTempGroupId, vtOffset) ; } //---------------------------------------------------------------------------- bool Machine::LoadMachineBase( const string& sName, const string& sGeo) { // recupero pezzo e layer della geometria originale della base string sPart, sLay ; Split( sGeo, "/", true, sPart, sLay) ; // cerco il gruppo nella geometria originale int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ; int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ; if ( nLay == GDB_ID_NULL) return false ; // lo sposto nella radice della macchina if ( ! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, m_nGroupId, GDB_FIRST_SON)) return false ; // gli assegno il nome m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ; // lo inserisco nel dizionario dei gruppi della macchina return m_mapGroups.emplace( sName, nLay).second ; } //---------------------------------------------------------------------------- bool Machine::LoadMachineTable( const string& sName, const string& sParent, int nType, const string& sGeo) { // recupero pezzo e layer della geometria originale della tavola string sPart, sLay ; Split( sGeo, "/", true, sPart, sLay) ; // cerco il gruppo nella geometria originale int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ; int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ; if ( nLay == GDB_ID_NULL) return false ; // cerco il gruppo padre per spostarvelo int nParentId = GetGroup( sParent) ; if ( nParentId == GDB_ID_NULL || ! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_FIRST_SON)) return false ; // gli assegno il nome m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ; // gli assegno il tipo string sInfo = MCH_TAB + ToString( nType) ; m_pMchMgr->m_pGeomDB->SetInfo( nLay, "Type", sInfo) ; // lo inserisco nel dizionario dei gruppi della macchina return m_mapGroups.emplace( sName, nLay).second ; } //---------------------------------------------------------------------------- bool Machine::LoadMachineAxis( const string& sName, const string& sParent, int nType, const Point3d& ptPos, const Vector3d& vtDir, const STROKE& Stroke, const string& sGeo, double dVal) { // recupero pezzo e layer della geometria originale dell'asse string sPart, sLay ; Split( sGeo, "/", true, sPart, sLay) ; // cerco il gruppo nella geometria originale int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ; int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ; if ( nLay == GDB_ID_NULL) return false ; // cerco il gruppo padre per spostarvelo int nParentId = GetGroup( sParent) ; if ( nParentId == GDB_ID_NULL || ! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_FIRST_SON)) return false ; // verifico che il valore sia nei limiti di corsa if ( dVal < Stroke.Min || dVal > Stroke.Max) return false ; // gli assegno il nome m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ; // gli assegno il tipo string sInfo = MCH_AXIS + ToString( nType) ; m_pMchMgr->m_pGeomDB->SetInfo( nLay, "Type", sInfo) ; // gli assegno la posizione m_pMchMgr->m_pGeomDB->SetInfo( nLay, "Pos", ptPos) ; // gli assegno la direzione m_pMchMgr->m_pGeomDB->SetInfo( nLay, "Dir", vtDir) ; // gli assegno i limiti di corsa m_pMchMgr->m_pGeomDB->SetInfo( nLay, "Stroke", ToString( Stroke.v)) ; // gli assegno il valore iniziale di home if ( ! m_pMchMgr->m_pGeomDB->SetInfo( nLay, "HVal", dVal)) return false ; // gli assegno il valore corrente if ( ! m_pMchMgr->m_pGeomDB->SetInfo( nLay, "Val", dVal)) return false ; // inserisco il vettore rappresentativo dell'asse if ( ! AddAxisVector( nLay, ptPos, vtDir, sName)) return false ; // lo inserisco nel dizionario dei gruppi della macchina return m_mapGroups.emplace( sName, nLay).second ; } //---------------------------------------------------------------------------- bool Machine::AddAxisVector( int nLay, const Point3d& ptPos, const Vector3d& vtDir, const string& sName) { // riferimento globale del gruppo asse Frame3d frFrame ; m_pMchMgr->m_pGeomDB->GetGroupGlobFrame( nLay, frFrame) ; // punto base e vettore in locale Point3d ptBase = ptPos ; ptBase.ToLoc( frFrame) ; Vector3d vtAxis = vtDir ; if ( ! vtAxis.Normalize()) return false ; vtAxis *= AXIS_LEN ; vtAxis.ToLoc( frFrame) ; // vettore geometrico PtrOwner pGeoVct( CreateGeoVector3d()) ; if ( IsNull( pGeoVct) || ! pGeoVct->Set( vtAxis, ptBase)) return false ; // lo inserisco al primo posto nel gruppo int nId = m_pMchMgr->m_pGeomDB->InsertGeoObj( GDB_ID_NULL, nLay, GDB_FIRST_SON, Release( pGeoVct)) ; if ( nId == GDB_ID_NULL) return false ; // gli assegno il nome di axis if ( ! m_pMchMgr->m_pGeomDB->SetName( nId, sName)) return false ; // gli assegno il colore blu if ( ! m_pMchMgr->m_pGeomDB->SetMaterial( nId, BLUE)) return false ; // lo nascondo if ( ! m_pMchMgr->m_pGeomDB->SetStatus( nId, GDB_ST_OFF)) return false ; return true ; } //---------------------------------------------------------------------------- bool Machine::LoadMachineStdHead( const string& sName, const string& sParent, const std::string& sHSet, const Point3d& ptPos, const Vector3d& vtTDir, const Vector3d& vtADir, const string& sGeo) { // recupero pezzo e layer della geometria originale dell'asse string sPart, sLay ; Split( sGeo, "/", true, sPart, sLay) ; // cerco il gruppo nella geometria originale int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ; int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ; if ( nLay == GDB_ID_NULL) return false ; // cerco il gruppo padre per spostarvelo int nParentId = GetGroup( sParent) ; if ( nParentId == GDB_ID_NULL || ! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_FIRST_SON)) return false ; // sistemo lo stato di visualizzazione bool bShow = ( sHSet == sName) ; m_pMchMgr->m_pGeomDB->SetStatus( nLay, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ; // gli assegno il nome m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ; // gli assegno l'insieme di teste e aggiorno il capostipite m_pMchMgr->m_pGeomDB->SetInfo( nLay, "HSet", sHSet) ; if ( ! AddHeadToSet( sHSet, sName)) return false ; // gli assegno il tipo string sInfo = MCH_HEAD + ToString( MCH_HT_STD) ; m_pMchMgr->m_pGeomDB->SetInfo( nLay, "Type", sInfo) ; // gli assegno la direzione ausiliaria m_pMchMgr->m_pGeomDB->SetInfo( nLay, "ADir", vtADir) ; // trasformazione del riferimento di uscita in gruppo di uscita MUEXITVECTOR vMuExit ; vMuExit.emplace_back( ptPos, vtTDir) ; if ( ! CreateExitGroups( nLay, vMuExit)) return false ; // lo inserisco nel dizionario dei gruppi della macchina return m_mapGroups.emplace( sName, nLay).second ; } //---------------------------------------------------------------------------- bool Machine::LoadMachineMultiHead( const string& sName, const string& sParent, const std::string& sHSet, const MUEXITVECTOR& vMuExit, const Vector3d& vtADir, const string& sGeo) { // recupero pezzo e layer della geometria originale dell'asse string sPart, sLay ; Split( sGeo, "/", true, sPart, sLay) ; // cerco il gruppo nella geometria originale int nPart = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( m_nTempGroupId, sPart) ; int nLay = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nPart, sLay) ; if ( nLay == GDB_ID_NULL) return false ; // cerco il gruppo padre per spostarvelo int nParentId = GetGroup( sParent) ; if ( nParentId == GDB_ID_NULL || ! m_pMchMgr->m_pGeomDB->RelocateGlob( nLay, nParentId, GDB_FIRST_SON)) return false ; // sistemo lo stato di visualizzazione bool bShow = ( sHSet == sName) ; m_pMchMgr->m_pGeomDB->SetStatus( nLay, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ; // gli assegno il nome m_pMchMgr->m_pGeomDB->SetName( nLay, sName) ; // gli assegno l'insieme teste e aggiorno il capostipite m_pMchMgr->m_pGeomDB->SetInfo( nLay, "HSet", sHSet) ; if ( ! AddHeadToSet( sHSet, sName)) return false ; // gli assegno il tipo string sInfo = MCH_HEAD + ToString( MCH_HT_MULTI) ; m_pMchMgr->m_pGeomDB->SetInfo( nLay, "Type", sInfo) ; // gli assegno la direzione ausiliaria m_pMchMgr->m_pGeomDB->SetInfo( nLay, "ADir", vtADir) ; // trasformazione dei riferimenti di uscita in gruppi di uscita if ( ! CreateExitGroups( nLay, vMuExit)) return false ; // lo inserisco nel dizionario dei gruppi della macchina return m_mapGroups.emplace( sName, nLay).second ; } //---------------------------------------------------------------------------- int Machine::GetGroup( const string& sGroup) { STRINT_UMAP::const_iterator Iter = m_mapGroups.find( sGroup) ; return (( Iter != m_mapGroups.end()) ? Iter->second : GDB_ID_NULL) ; } //---------------------------------------------------------------------------- bool Machine::IsAxisGroup( int nGroup) { string sType ; return ( m_pMchMgr->m_pGeomDB->GetInfo( nGroup, "Type", sType) && sType[0] == MCH_AXIS) ; } //---------------------------------------------------------------------------- bool Machine::IsTableGroup( int nGroup) { string sType ; return ( m_pMchMgr->m_pGeomDB->GetInfo( nGroup, "Type", sType) && sType[0] == MCH_TAB) ; } //---------------------------------------------------------------------------- bool Machine::IsHeadGroup( int nGroup) { string sType ; return ( m_pMchMgr->m_pGeomDB->GetInfo( nGroup, "Type", sType) && sType[0] == MCH_HEAD) ; } //---------------------------------------------------------------------------- bool Machine::AddHeadToSet( const string& sHSet, const string& sName) { // se il capo-insieme coincide con la testa, non devo fare alcunchč if ( sHSet == sName) return true ; // recupero le info della testa capo-insieme int nHGroupId = GetGroup( sHSet) ; if ( nHGroupId == GDB_ID_NULL) return false ; STRVECTOR vsHSet ; if ( ! m_pMchMgr->m_pGeomDB->GetInfo( nHGroupId, "HSet", vsHSet)) return false ; // se giā presente non devo fare alcunchč, altrimenti lo aggiungo if ( find( vsHSet.begin(), vsHSet.end(), sName) != vsHSet.end()) return true ; vsHSet.emplace_back( sName) ; return m_pMchMgr->m_pGeomDB->SetInfo( nHGroupId, "HSet", vsHSet) ; } //---------------------------------------------------------------------------- bool Machine::GetHSet( const string& sHead, STRVECTOR& vsHSet) { // recupero l'indice della testa int nHead = GetGroup( sHead) ; if ( ! IsHeadGroup( nHead)) return false ; // recupero la stringa dell'insieme di teste if ( ! m_pMchMgr->m_pGeomDB->GetInfo( nHead, "HSet", vsHSet)) return false ; // se il primo membro coincide con la testa, allora č giā l'insieme di teste if ( vsHSet[0] == sHead) return true ; // altrimenti cerco l'insieme della prima testa return GetHSet( vsHSet[0], vsHSet) ; } //---------------------------------------------------------------------------- bool Machine::EnableHeadInSet( const string& sHead) { // recupero l'insieme di teste STRVECTOR vsHSet ; if ( ! GetHSet( sHead, vsHSet)) return false ; // spengo tutte le teste tranne questa for ( size_t i = 0 ; i < vsHSet.size() ; ++ i) { int nH = GetGroup( vsHSet[i]) ; bool bShow = ( vsHSet[i] == sHead) ; m_pMchMgr->m_pGeomDB->SetStatus( nH, ( bShow ? GDB_ST_ON : GDB_ST_OFF)) ; } return true ; } //---------------------------------------------------------------------------- bool Machine::CreateExitGroups( int nLay, const MUEXITVECTOR& vMuExit) { // ciclo sulle uscite for ( int i = 0 ; i < int( vMuExit.size()) ; ++ i) { string sName = "T" + ToString( i+1) ; // se trovo riferimento per uscita, lo sostituisco con gruppo equivalente int nT = m_pMchMgr->m_pGeomDB->GetFirstNameInGroup( nLay, sName) ; if ( nT != GDB_ID_NULL && m_pMchMgr->m_pGeomDB->GetGeoType( nT) == GEO_FRAME3D) { const Frame3d& frFrame = GetGeoFrame3d( m_pMchMgr->m_pGeomDB->GetGeoObj( nT))->GetFrame() ; int nGT = m_pMchMgr->m_pGeomDB->InsertGroup( GDB_ID_NULL, nT, GDB_AFTER, frFrame) ; if ( nGT == GDB_ID_NULL) { string sOut = "Error inserting group " + sName ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; return false ; } m_pMchMgr->m_pGeomDB->Erase( nT) ; // assegno nome m_pMchMgr->m_pGeomDB->SetName( nGT, sName) ; // gli assegno la posizione m_pMchMgr->m_pGeomDB->SetInfo( nGT, "Pos", vMuExit[i].ptPos) ; // gli assegno la direzione utensile m_pMchMgr->m_pGeomDB->SetInfo( nGT, "TDir", vMuExit[i].vtTDir) ; } else { string sOut = "Error finding frame " + sName ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; return false ; } } return true ; }