//---------------------------------------------------------------------------- // 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 "Table.h" #include "Axis.h" #include "Head.h" #include "Exit.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) ; // installo e inizializzo il gestore della tavola Table* pTab = new(nothrow) Table ; if ( pTab == nullptr) return false ; pTab->Set( sName, nType) ; m_pMchMgr->m_pGeomDB->SetObjUser( nLay, pTab) ; // 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) ; // installo e inizializzo il gestore dell'asse Axis* pAxis = new(nothrow) Axis ; if ( pAxis == nullptr) return false ; pAxis->Set( sName, nType, ptPos, vtDir, Stroke, dVal) ; m_pMchMgr->m_pGeomDB->SetObjUser( nLay, pAxis) ; // 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) ; // installo e inizializzo il gestore della testa Head* pHead = new(nothrow) Head ; if ( pHead == nullptr) return false ; pHead->Set( sName, MCH_HT_STD, sHSet, vtADir) ; m_pMchMgr->m_pGeomDB->SetObjUser( nLay, pHead) ; // aggiorno la testa capostipite if ( ! AddHeadToSet( sHSet, sName)) return false ; // 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) ; // installo e inizializzo il gestore della testa Head* pHead = new(nothrow) Head ; if ( pHead == nullptr) return false ; pHead->Set( sName, MCH_HT_MULTI, sHSet, vtADir) ; m_pMchMgr->m_pGeomDB->SetObjUser( nLay, pHead) ; // aggiorno la testa capostipite if ( ! AddHeadToSet( sHSet, sName)) return false ; // 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) ; } //---------------------------------------------------------------------------- Axis* Machine::GetAxis( int nGroup) { return ( dynamic_cast( m_pMchMgr->m_pGeomDB->GetObjUser( nGroup))) ; } //---------------------------------------------------------------------------- Table* Machine::GetTable( int nGroup) { return ( dynamic_cast( m_pMchMgr->m_pGeomDB->GetObjUser( nGroup))) ; } //---------------------------------------------------------------------------- Head* Machine::GetHead( int nGroup) { return ( dynamic_cast( m_pMchMgr->m_pGeomDB->GetObjUser( nGroup))) ; } //---------------------------------------------------------------------------- Exit* Machine::GetExit( int nGroup) { return ( dynamic_cast( m_pMchMgr->m_pGeomDB->GetObjUser( nGroup))) ; } //---------------------------------------------------------------------------- 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 la testa capo-insieme Head* pHead = GetHead( GetGroup( sHSet)) ; if ( pHead == nullptr) return false ; // aggiungo questa testa all'insieme return pHead->AddHeadToHSet( sName) ; } //---------------------------------------------------------------------------- const STRVECTOR& Machine::GetHSet( const string& sHead) { // vettore di stringhe vuoto, da restituire in caso di errore static const STRVECTOR vsNull ; // recupero la testa Head* pHead = GetHead( GetGroup( sHead)) ; if ( pHead == nullptr) return vsNull ; // recupero l'insieme di teste a cui appartiene const STRVECTOR& vsTmp = pHead->GetHSet() ; if ( vsTmp.empty()) return vsNull ; // se il primo membro coincide con la testa, allora č giā l'insieme di teste if ( vsTmp[0] == sHead) return vsTmp ; // altrimenti cerco l'insieme della prima testa return GetHSet( vsTmp[0]) ; } //---------------------------------------------------------------------------- bool Machine::EnableHeadInSet( const string& sHead) { // recupero l'insieme di teste const STRVECTOR& vsHSet = GetHSet( sHead) ; if ( vsHSet.empty()) 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 = MCH_EXIT + 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) ; // installo e inizializzo il gestore dell'uscita Exit* pExit = new(nothrow) Exit ; if ( pExit == nullptr) return false ; pExit->Set( sName, vMuExit[i].ptPos, vMuExit[i].vtTDir) ; m_pMchMgr->m_pGeomDB->SetObjUser( nGT, pExit) ; } else { string sOut = "Error finding frame " + sName ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; return false ; } } return true ; }