//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : Drilling.cpp Data : 29.04.16 Versione : 1.6p4 // Contenuto : Implementazione gestione disposizione. // // // // Modifiche : 21.05.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "MachMgr.h" #include "DllMain.h" #include "Disposition.h" #include "/EgtDev/Include/EMkDispositionConst.h" #include "/EgtDev/Include/EGkAngle.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUserObjFactory.h" #include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EGnFileUtils.h" using namespace std ; //---------------------------------------------------------------------------- static std::string DIS_TABLE = "Tab" ; static std::string DIS_PHASE = "Ph" ; static std::string DIS_REF1 = "Ref1" ; static std::string DIS_AREA1 = "Area1" ; static std::string DIS_FXD_TOT = "FxT" ; static std::string DIS_FXD_NAME = "FxN" ; static std::string DIS_FXD_POS = "FxP" ; static std::string DIS_FXD_ANG = "FxA" ; static std::string DIS_FXD_MOV = "FxM" ; static std::string DIS_MVD_TOT = "MvT" ; static std::string DIS_MVD_ID = "MvI" ; static std::string DIS_MVD_TYPE = "MvT" ; static std::string DIS_MVD_PNT = "MvP" ; static std::string DIS_MVD_ANG = "MvA" ; static std::string DIS_MVD_FLAG = "MvF" ; static std::string DIS_NUM = "NUM" ; static std::string DIS_HEAD = "Head" ; static std::string DIS_EXIT = "Exit" ; static std::string DIS_SOMEBYHAND = "Sbh" ; //---------------------------------------------------------------------------- USEROBJ_REGISTER( "EMkDisposition", Disposition) ; //---------------------------------------------------------------------------- const string& Disposition::GetClassName( void) const { return USEROBJ_GETNAME( Disposition) ; } //---------------------------------------------------------------------------- Disposition* Disposition::Clone( void) const { // alloco oggetto Disposition* pDisp = new(nothrow) Disposition ; // eseguo copia dei dati if ( pDisp != nullptr) { try { pDisp->m_sTabName = m_sTabName ; pDisp->m_ptRef1 = m_ptRef1 ; pDisp->m_b3Area1 = m_b3Area1 ; pDisp->m_bTabOk = m_bTabOk ; pDisp->m_vFixData = m_vFixData ; pDisp->m_vMvrData = m_vMvrData ; pDisp->m_sHead = m_sHead ; pDisp->m_nExit = m_nExit ; pDisp->m_nShifts = m_nShifts ; pDisp->m_bSomeByHand = m_bSomeByHand ; } catch( ...) { delete pDisp ; return nullptr ; } } // ritorno l'oggetto return pDisp ; } //---------------------------------------------------------------------------- bool Disposition::Dump( string& sOut, bool bMM, const char* szNewLine) const { sOut += GetClassName() + "[mm]" + szNewLine ; sOut += "Tab=" + m_sTabName + ( m_bTabOk ? " (ok)" : " (to verify)") + szNewLine ; sOut += "Phase=" + ToString( m_nPhase) + szNewLine ; sOut += "Ref1=(" + ToString( m_ptRef1, 3) + ")" + szNewLine ; sOut += "Area1=(" + ToString( m_b3Area1, 3) + ")" + szNewLine ; for ( const auto& FixData : m_vFixData) { sOut += "FxD=" + FixData.sName + "," + ToString( FixData.nId) + ",(" + ToString( FixData.ptPos) + ")," + ToString( FixData.dAng) + "," + ToString( FixData.dMov) + szNewLine ; } for ( const auto& MvrData : m_vMvrData) { sOut += "MvD=" + ToString( MvrData.nRawId) + "," ; switch ( MvrData.nType) { case MoveRawData::NONE : sOut += string( " NONE") + szNewLine ; break ; case MoveRawData::COR : sOut += " COR,(" + ToString( MvrData.ptP) + ")," + ToString( MvrData.nFlag) + szNewLine ; break ; case MoveRawData::CEN : sOut += " CEN,(" + ToString( MvrData.ptP) + ")," + ToString( MvrData.nFlag) + szNewLine ; break ; case MoveRawData::ROT : sOut += " ROT,(" + ToString( MvrData.ptP) + ")" + szNewLine ; break ; } } sOut += "Num=" + ToString( m_nShifts) + szNewLine ; sOut += "Head=" + m_sHead + szNewLine ; sOut += "Exit=" + ToString( m_nExit) + szNewLine ; sOut += "ByHand=" + ToString( m_bSomeByHand) + szNewLine ; return true ; } //---------------------------------------------------------------------------- bool Disposition::Save( STRVECTOR& vString) const { try { int k = - 1 ; int nFxdTot = int( m_vFixData.size()) ; int nFxdLines = 1 + 4 * nFxdTot ; int nMvdTot = int( m_vMvrData.size()) ; int nMvdLines = 1 + 4 * nMvdTot ; int nOther = 4 ; vString.insert( vString.begin(), 4 + nFxdLines + nMvdLines + nOther, "") ; // Nome if ( ! SetVal( DIS_TABLE, m_sTabName, vString[++k])) return false ; // Fase if ( ! SetVal( DIS_PHASE, m_nPhase, vString[++k])) return false ; // Primo riferimento if ( ! SetVal( DIS_REF1, m_ptRef1, vString[++k])) return false ; // Prima area if ( ! SetVal( DIS_AREA1, m_b3Area1, vString[++k])) return false ; // Dati sottopezzi if ( ! SetVal( DIS_FXD_TOT, nFxdTot, vString[++k])) return false ; for ( const auto& FixData : m_vFixData) { if ( ! SetVal( DIS_FXD_NAME, FixData.sName, vString[++k]) || ! SetVal( DIS_FXD_POS, FixData.ptPos, vString[++k]) || ! SetVal( DIS_FXD_ANG, FixData.dAng, vString[++k]) || ! SetVal( DIS_FXD_MOV, FixData.dMov, vString[++k])) return false ; } // Dati posizionamento grezzi if ( ! SetVal( DIS_MVD_TOT, nMvdTot, vString[++k])) return false ; for ( const auto& MvrData : m_vMvrData) { if ( ! SetVal( DIS_MVD_ID, MvrData.nRawId, vString[++k]) || ! SetVal( DIS_MVD_TYPE, MvrData.nType, vString[++k]) || ! SetVal( DIS_MVD_PNT, MvrData.ptP, vString[++k]) || ! SetVal( DIS_MVD_FLAG, MvrData.nFlag, vString[++k])) return false ; } // altri dati if ( ! SetVal( DIS_NUM, m_nShifts, vString[++k])) return false ; if ( ! SetVal( DIS_HEAD, m_sHead, vString[++k])) return false ; if ( ! SetVal( DIS_EXIT, m_nExit, vString[++k])) return false ; if ( ! SetVal( DIS_SOMEBYHAND, m_bSomeByHand, vString[++k])) return false ; } catch( ...) { return false ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::Load( const STRVECTOR& vString, int nBaseGdbId) { if ( vString.size() < 5) return false ; int k = - 1 ; // nome della tavola m_bTabOk = false ; if ( ! GetVal( vString[++k], DIS_TABLE, m_sTabName)) return false ; // fase opzionale if ( ! GetVal( vString[++k], DIS_PHASE, m_nPhase)) -- k ; // primo riferimento if ( ! GetVal( vString[++k], DIS_REF1, m_ptRef1)) return false ; // prima area if ( ! GetVal( vString[++k], DIS_AREA1, m_b3Area1)) return false ; // dati sottopezzi int nFxdTot ; if ( ! GetVal( vString[++k], DIS_FXD_TOT, nFxdTot)) return false ; int nFxdLines = 1 + 3 * nFxdTot ; if ( int( vString.size()) < 3 + nFxdLines + 1) return false ; m_vFixData.insert( m_vFixData.begin(), nFxdTot, FixtureData()) ; for ( auto& FixData : m_vFixData) { // dati obbligatori if ( ! GetVal( vString[++k], DIS_FXD_NAME, FixData.sName) || ! GetVal( vString[++k], DIS_FXD_POS, FixData.ptPos) || ! GetVal( vString[++k], DIS_FXD_ANG, FixData.dAng)) return false ; // dati facoltativi if ( k + 1 < int( vString.size())) { if ( ! GetVal( vString[++k], DIS_FXD_MOV, FixData.dMov)) -- k ; } } // dati posizionamento grezzi int nMvdTot ; if ( ! GetVal( vString[++k], DIS_MVD_TOT, nMvdTot)) return false ; int nMvdLines = 1 + 4 * nMvdTot ; if ( int( vString.size()) < 3 + nFxdLines + nMvdLines) return false ; m_vMvrData.insert( m_vMvrData.begin(), nMvdTot, MoveRawData()) ; for ( auto& MvrData : m_vMvrData) { if ( ! GetVal( vString[++k], DIS_MVD_ID, MvrData.nRawId) || ! GetVal( vString[++k], DIS_MVD_TYPE, MvrData.nType) || ! GetVal( vString[++k], DIS_MVD_PNT, MvrData.ptP) || ! GetVal( vString[++k], DIS_MVD_FLAG, MvrData.nFlag)) return false ; MvrData.nRawId += nBaseGdbId ; } // altri dati aggiuntivi if ( k + 1 < int( vString.size())) { if ( ! GetVal( vString[++k], DIS_NUM, m_nShifts)) return false ; } if ( k + 1 < int( vString.size())) { if ( ! GetVal( vString[++k], DIS_HEAD, m_sHead)) return false ; } if ( k + 1 < int( vString.size())) { if ( ! GetVal( vString[++k], DIS_EXIT, m_nExit)) return false ; } if ( k + 1 < int( vString.size())) { if ( ! GetVal( vString[++k], DIS_SOMEBYHAND, m_bSomeByHand)) return false ; } return true ; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- Disposition::Disposition( void) : m_bTabOk( false), m_nExit( 0), m_nShifts( 0), m_bSomeByHand( false) { } //---------------------------------------------------------------------------- bool Disposition::SetTable( const string& sTable) { // dichiaro tavola non verificata m_bTabOk = false ; // verifico il gestore lavorazioni if ( m_pMchMgr == nullptr) return false ; // recupero la macchina corrente Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr) return false ; // imposta questa tavola come corrente if ( ! pMch->SetCurrTable( sTable)) return false ; // recupero il primo riferimento e l'area utile della tavola Point3d ptPrevRef1 = m_ptRef1 ; if ( ! pMch->GetCurrTableRef1( m_ptRef1) || ! pMch->GetCurrTableArea1( m_b3Area1)) return false ; if ( ! m_sTabName.empty() && EqualNoCase( m_sTabName, sTable) && ! AreSamePointApprox( ptPrevRef1, m_ptRef1)) { string sOut = "Table Ref1 changed : (" + ToString( ptPrevRef1) + ") -> (" + ToString( m_ptRef1) +")" ; LOG_INFO( GetEMkLogger(), sOut.c_str()) ; } // salvo il nome e dichiaro tavola verificata m_sTabName = sTable ; m_bTabOk = true ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetTable( string& sTable) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico tavola if ( ! m_bTabOk && ! const_cast(this)->SetTable( m_sTabName)) return false ; // recupero il nome della tavola sTable = m_sTabName ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetTableRef1( Point3d& ptRef1) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico tavola if ( ! m_bTabOk && ! const_cast(this)->SetTable( m_sTabName)) return false ; // recupero il primo riferimento della tavola ptRef1 = m_ptRef1 ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetTableArea1( BBox3d& b3Area1) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico tavola if ( ! m_bTabOk && ! const_cast(this)->SetTable( m_sTabName)) return false ; // recupero la prima area utile della tavola b3Area1 = m_b3Area1 ; return true ; } //---------------------------------------------------------------------------- bool Disposition::Apply( bool bVerifyTab) { // verifico tavola if ( ( ! m_bTabOk || bVerifyTab) && ! SetTable( m_sTabName)) return false ; // aggiornamento sottopezzi for ( auto& FixData : m_vFixData) { // se sottopezzo da caricare if ( FixData.nId == GDB_ID_NULL) { int nId = AddFixture( FixData.sName, FixData.ptPos, FixData.dAng, FixData.dMov, false) ; if ( nId == GDB_ID_NULL) { string sOut = "Error adding fixture " + FixData.sName ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } else FixData.nId = nId ; } // altrimenti sottopezzo da rimettere in posizione else { if ( ! PlaceFixture( FixData.nId, FixData.ptPos, FixData.dAng, FixData.dMov)) { string sOut = "Error placing fixture " + ToString( FixData.nId) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } } } // annullo movimento grezzi int nRawId = m_pMchMgr->GetFirstRawPart() ; while ( nRawId != GDB_ID_NULL) { if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) { // recupero riferimento del grezzo Frame3d* pfrRaw = m_pGeomDB->GetGroupFrame( nRawId) ; // lo trasformo nel riferimento globale pfrRaw->Reset() ; } nRawId = m_pMchMgr->GetNextRawPart( nRawId) ; } // aggiornamento movimento grezzi for ( const auto& vMvrData : m_vMvrData) { switch ( vMvrData.nType) { case MoveRawData::COR : if ( ! MoveToCornerRawPart( vMvrData.nRawId, vMvrData.ptP, vMvrData.nFlag, false)) { string sOut = "Error in MoveToCornerRawPart " + ToString( vMvrData.nRawId) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } break ; case MoveRawData::CEN : if ( ! MoveToCenterRawPart( vMvrData.nRawId, vMvrData.ptP, vMvrData.nFlag, false)) { string sOut = "Error in MoveToCenterRawPart " + ToString( vMvrData.nRawId) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } break ; case MoveRawData::ROT : if ( ! ApplyRotationToRawPart( vMvrData.nRawId, vMvrData.ptP.x, vMvrData.ptP.y, vMvrData.ptP.z)) { string sOut = "Error in ApplyRotationToRawPart " + ToString( vMvrData.nRawId) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) ; } break ; } } return true ; } //---------------------------------------------------------------------------- int Disposition::AddFixture( const string& sName, const Point3d& ptPos, double dAngDeg, double dMov, bool bAddToList) { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return GDB_ID_NULL ; // verifico tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return GDB_ID_NULL ; // verifico che la posizione sia nell'area della tavola if ( ! m_b3Area1.EnclosesXY( m_ptRef1 + ptPos)) return GDB_ID_NULL ; // Nome tutto maiuscolo string sMyName = sName ; ToUpper( sMyName) ; // Se recuperabile dal gruppo dei bloccaggi int nFixtId = m_pMchMgr->GetUnusedFixture( sMyName, m_nPhase) ; if ( nFixtId != GDB_ID_NULL) { // aggiungo la fase al bloccaggio INTVECTOR vPhase ; m_pMchMgr->GetFixturePhases( nFixtId, vPhase) ; vPhase.push_back( m_nPhase) ; m_pGeomDB->SetInfo( nFixtId, MACH_FXT_PHASE, vPhase) ; // aggiorno visualizzazione m_pGeomDB->SetStatus( nFixtId, GDB_ST_ON) ; } // altrimenti lo carico da file else { // recupero il gruppo delle fixtures nella macchinata corrente int nFixtGrpId = m_pMchMgr->GetCurrFixtGroupId() ; if ( nFixtGrpId == GDB_ID_NULL) return GDB_ID_NULL ; // verifico esistenza file sottopezzo string sFixtFile = m_pMchMgr->GetCurrFixtDir() + "\\" + sName + ".Nge" ; if ( ! ExistsFile( sFixtFile)) return GDB_ID_NULL ; // inserisco il sottopezzo nel gruppo if ( ! m_pGeomDB->Load( sFixtFile, nFixtGrpId)) return GDB_ID_NULL ; nFixtId = m_pGeomDB->GetLastGroupInGroup( nFixtGrpId) ; if ( nFixtId == GDB_ID_NULL) return GDB_ID_NULL ; // assegno il nome m_pGeomDB->SetName( nFixtId, sMyName) ; // imposto il livello a temporaneo m_pGeomDB->SetLevel( nFixtId, GDB_LV_TEMP) ; // aggiungo la fase al bloccaggio m_pGeomDB->SetInfo( nFixtId, MACH_FXT_PHASE, m_nPhase) ; } // resetto il riferimento del gruppo Frame3d* pfrFixt = m_pGeomDB->GetGroupFrame( nFixtId) ; pfrFixt->Reset() ; // la muovo nella posizione voluta Vector3d vtMove = ( m_ptRef1 + ptPos) - ORIG ; m_pGeomDB->TranslateGlob( nFixtId, vtMove) ; // la ruoto if ( fabs( dAngDeg) > EPS_ANG_SMALL) m_pGeomDB->RotateGroup( nFixtId, ORIG, Z_AX, dAngDeg) ; // muovo eventuale parte mobile int nMobId = m_pGeomDB->GetFirstNameInGroup( nFixtId, FXT_MOBILE) ; if ( nMobId != GDB_ID_NULL) { double dCurrVal = 0 ; m_pGeomDB->GetInfo( nMobId, FXT_MOB_CPOS, dCurrVal) ; if ( abs( dMov - dCurrVal) > EPS_SMALL) { m_pGeomDB->TranslateGroup( nMobId, Vector3d( 0, 0, dMov - dCurrVal)) ; m_pGeomDB->SetInfo( nMobId, FXT_MOB_CPOS, dMov) ; } } // se da aggiungere alla lista if ( bAddToList) m_vFixData.emplace_back( sName, nFixtId, ptPos, dAngDeg, dMov) ; return nFixtId ; } //---------------------------------------------------------------------------- int Disposition::GetFirstFixture( void) { // verifico se ci sono bloccaggi if ( m_vFixData.empty()) return GDB_ID_NULL ; // recupero il primo int nId = m_vFixData.front().nId ; // ne verifico la validità if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false)) return GDB_ID_NULL ; return nId ; } //---------------------------------------------------------------------------- int Disposition::GetNextFixture( int nId) { // ciclo sui bloccaggi int nFxtTot = int( m_vFixData.size()) ; for ( int i = 0 ; i < nFxtTot ; ++ i) { // se trovato if ( m_vFixData[i].nId == nId) { // se esiste successivo e valido int j = i + 1 ; if ( j < nFxtTot && m_pMchMgr != nullptr && m_pMchMgr->VerifyFixture( m_vFixData[j].nId, false)) return m_vFixData[j].nId ; else return GDB_ID_NULL ; } } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- bool Disposition::MoveFixture( int nId, const Vector3d& vtMove) { // verifica validità sottopezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // verifico che la posizione finale sia nell'area della tavola Frame3d frFixt ; if ( ! m_pGeomDB->GetGroupFrame( nId, frFixt) || ! m_b3Area1.EnclosesXY( frFixt.Orig() + vtMove)) return false ; // muovo l'oggetto m_pGeomDB->TranslateGlob( nId, vtMove) ; // aggiorno la posizione dell'oggetto nel vettore dei comandi for ( auto& FixData : m_vFixData) { if ( FixData.nId == nId) { FixData.ptPos += vtMove ; break ; } } return true ; } //---------------------------------------------------------------------------- bool Disposition::RotateFixture( int nId, double dDeltaAngDeg) { // verifica validità sottopezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // ruoto l'oggetto m_pGeomDB->RotateGroup( nId, ORIG, Z_AX, dDeltaAngDeg) ; // aggiorno la posizione dell'oggetto nel vettore dei comandi for ( auto& FixData : m_vFixData) { if ( FixData.nId == nId) { FixData.dAng += dDeltaAngDeg ; break ; } } return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveFixtureMobile( int nId, double dDeltaMov) { // verifica validità sottopezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // muovo eventuale parte mobile int nMobId = m_pGeomDB->GetFirstNameInGroup( nId, FXT_MOBILE) ; if ( nMobId != GDB_ID_NULL) { double dCurrVal = 0 ; m_pGeomDB->GetInfo( nMobId, FXT_MOB_CPOS, dCurrVal) ; if ( abs( dDeltaMov) > EPS_SMALL) { m_pGeomDB->TranslateGroup( nMobId, Vector3d( 0, 0, dDeltaMov)) ; m_pGeomDB->SetInfo( nMobId, FXT_MOB_CPOS, ( dCurrVal + dDeltaMov)) ; } } // aggiorno la posizione dell'oggetto nel vettore dei comandi for ( auto& FixData : m_vFixData) { if ( FixData.nId == nId) { FixData.dMov += dDeltaMov ; break ; } } return true ; } //---------------------------------------------------------------------------- bool Disposition::PlaceFixture( int nId, const Point3d& ptPos, double dAngDeg, double dMov) { // verifica validità sottopezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // verifico che la posizione sia nell'area della tavola if ( ! m_b3Area1.EnclosesXY( m_ptRef1 + ptPos)) return false ; // aggiorno visualizzazione m_pGeomDB->SetStatus( nId, GDB_ST_ON) ; // resetto il riferimento del gruppo Frame3d* pfrFixt = m_pGeomDB->GetGroupFrame( nId) ; pfrFixt->Reset() ; // lo muovo nella posizione voluta Vector3d vtMove = ( m_ptRef1 + ptPos) - ORIG ; m_pGeomDB->TranslateGlob( nId, vtMove) ; // lo ruoto if ( fabs( dAngDeg) > EPS_ANG_SMALL) m_pGeomDB->RotateGroup( nId, ORIG, Z_AX, dAngDeg) ; // muovo eventuale parte mobile int nMobId = m_pGeomDB->GetFirstNameInGroup( nId, FXT_MOBILE) ; if ( nMobId != GDB_ID_NULL) { double dCurrVal = 0 ; m_pGeomDB->GetInfo( nMobId, FXT_MOB_CPOS, dCurrVal) ; if ( abs( dMov - dCurrVal) > EPS_SMALL) { m_pGeomDB->TranslateGroup( nMobId, Vector3d( 0, 0, dMov - dCurrVal)) ; m_pGeomDB->SetInfo( nMobId, FXT_MOB_CPOS, dMov) ; } } // aggiorno la posizione dell'oggetto nel vettore dei comandi for ( auto& FixData : m_vFixData) { if ( FixData.nId == nId) { FixData.ptPos = ptPos ; FixData.dAng = dAngDeg ; FixData.dMov = dMov ; break ; } } return true ; } //---------------------------------------------------------------------------- bool Disposition::RemoveFixture( int nId) { // verifica validità sottopezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // dichiaro l'oggetto non più usato dalla fase INTVECTOR vPhase ; if ( ! m_pMchMgr->GetFixturePhases( nId, vPhase)) return false ; auto iIter = find( vPhase.begin(), vPhase.end(), m_nPhase) ; if ( iIter != vPhase.end()) { vPhase.erase( iIter) ; m_pGeomDB->SetInfo( nId, MACH_FXT_PHASE, vPhase) ; } // rimuovo l'oggetto dal vettore dei comandi while ( true) { auto iIter = find_if( m_vFixData.begin(), m_vFixData.end(), [ nId]( const FixtureData& Fxt) { return ( Fxt.nId == nId) ; }) ; if ( iIter == m_vFixData.end()) break ; else m_vFixData.erase( iIter) ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveToCornerRawPart( int nRawId, const Point3d& ptP, int nFlag, bool bAddToList) { // verifica validità grezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false)) return false ; // recupero il solido int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; // determino il box del grezzo (solo il solido ovviamente) BBox3d b3Raw ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw)) return false ; // calcolo il movimento necessario Vector3d vtMove ; switch ( nFlag) { case MCH_CR_TL : vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMin().x, b3Raw.GetMax().y, b3Raw.GetMin().z) ; break ; case MCH_CR_TR : vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, b3Raw.GetMax().y, b3Raw.GetMin().z) ; break ; default : // RPCP_BL vtMove = ( m_ptRef1 + ptP) - b3Raw.GetMin() ; break ; case MCH_CR_BR : vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, b3Raw.GetMin().y, b3Raw.GetMin().z) ; break ; } // verifico se il grezzo nella posizione finale sarà nella tavola b3Raw.Translate( vtMove) ; if ( ! m_b3Area1.EnclosesXY( b3Raw)) return false ; // recupero eventuale spostamento corrente della tavola Vector3d vtDelta1 ; Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr || ! pMch->GetCurrTableDeltaRef1( vtDelta1)) return false ; // eseguo traslazione in globale Vector3d vtTotMove = vtMove + vtDelta1 ; if ( ! vtTotMove.IsSmall()) m_pGeomDB->TranslateGlob( nRawId, vtTotMove) ; // se da aggiungere alla lista if ( bAddToList) { auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; if ( iIter == m_vMvrData.end()) m_vMvrData.emplace_back( nRawId, MoveRawData::COR, ptP, nFlag) ; else *iIter = MoveRawData( nRawId, MoveRawData::COR, ptP, nFlag) ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveToCenterRawPart( int nRawId, const Point3d& ptP, int nFlag, bool bAddToList) { // verifica validità grezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false)) return false ; // recupero il solido int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; // determino il box del grezzo (solo il solido ovviamente) BBox3d b3Raw ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw)) return false ; // ricavo il centro dal box (in generale non è il centro geometrico) Point3d ptCen ; b3Raw.GetCenter( ptCen) ; // calcolo il movimento necessario Vector3d vtMove ; switch ( nFlag) { case MCH_CE_TC : vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, b3Raw.GetMax().y, ptCen.z) ; break ; default : // RPCE_ML vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMin().x, ptCen.y, ptCen.z) ; break ; case MCH_CE_MR : vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, ptCen.y, ptCen.z) ; break ; case MCH_CE_BC : vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, b3Raw.GetMin().y, ptCen.z) ; break ; case MCH_CE_MC : vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, ptCen.y, b3Raw.GetMin().z) ; break ; } // verifico se il grezzo nella posizione finale sarà nella tavola b3Raw.Translate( vtMove) ; if ( ! m_b3Area1.EnclosesXY( b3Raw)) return false ; // eseguo traslazione in globale if ( ! vtMove.IsSmall()) m_pGeomDB->TranslateGlob( nRawId, vtMove) ; // se da aggiungere alla lista if ( bAddToList) { auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; if ( iIter == m_vMvrData.end()) m_vMvrData.emplace_back( nRawId, MoveRawData::CEN, ptP, nFlag) ; else *iIter = MoveRawData( nRawId, MoveRawData::CEN, ptP, nFlag) ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveRawPart( int nRawId, const Vector3d& vtMove) { // verifica validità grezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false)) return false ; // se movimento nullo, non devo fare alcunché if ( vtMove.IsSmall()) return true ; // verifico ci sia già un movimento assoluto di questo grezzo auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; if ( iIter == m_vMvrData.end()) return false ; // recupero il solido int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; // determino il box del grezzo (solo il solido ovviamente) BBox3d b3Raw ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw)) return false ; // recupero eventuale spostamento corrente della tavola Vector3d vtDelta1 ; Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr || ! pMch->GetCurrTableDeltaRef1( vtDelta1)) return false ; // verifico se il grezzo nella posizione finale sarà nella tavola b3Raw.Translate( vtMove - vtDelta1) ; if ( ! m_b3Area1.EnclosesXY( b3Raw)) return false ; // eseguo traslazione in globale m_pGeomDB->TranslateGlob( nRawId, vtMove) ; // aggiorno comando di movimento iIter->ptP += vtMove ; return true ; } //---------------------------------------------------------------------------- bool Disposition::RotateRawPart( int nRawId, const Vector3d& vtAx, double dAngRotDeg) { // verifica validità grezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false)) return false ; // recupero centro del grezzo Point3d ptAx ; if ( ! m_pMchMgr->GetRawPartCenter( nRawId, ptAx)) return false ; // eseguo rotazione in globale attorno al centro del grezzo if ( ! m_pGeomDB->RotateGlob( nRawId, ptAx, vtAx, dAngRotDeg)) return false ; // recupero riferimento globale del grezzo Frame3d frRaw ; m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw) ; // ne calcolo gli angoli di Eulero double dAngCDeg, dAngADeg, dAngC1Deg ; frRaw.GetRotationsCAC1( dAngCDeg, dAngADeg, dAngC1Deg) ; // aggiungo o modifico nella lista auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && Mrv.nType == MoveRawData::ROT) ; }) ; if ( iIter == m_vMvrData.end()) m_vMvrData.emplace_back( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ; else *iIter = MoveRawData( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ; return true ; } //---------------------------------------------------------------------------- bool Disposition::ApplyRotationToRawPart( int nRawId, double dAngCDeg, double dAngADeg, double dAngC1Deg) { // verifica validità grezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false)) return false ; // recupero centro del grezzo Point3d ptCen ; if ( ! m_pMchMgr->GetRawPartCenter( nRawId, ptCen)) return false ; // recupero riferimento del grezzo (coincide con quello globale) Frame3d* pfrRaw = m_pGeomDB->GetGroupFrame( nRawId) ; // lo trasformo nel nuovo riferimento Point3d ptOrig = pfrRaw->Orig() ; // necessario copiarlo pfrRaw->Set( ptOrig, dAngCDeg, dAngADeg, dAngC1Deg) ; // recupero nuovo centro del grezzo Point3d ptNewCen ; if ( ! m_pMchMgr->GetRawPartCenter( nRawId, ptNewCen)) return false ; // eseguo spostamento per riportare il centro nella posizione originale pfrRaw->Translate( ptCen - ptNewCen) ; return true ; } //---------------------------------------------------------------------------- bool Disposition::RemoveRawPart( int nRawId) { // verifica validità grezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false)) return false ; // elimino i movimenti registrati per questo grezzo while ( true) { auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId) ; }) ; if ( iIter == m_vMvrData.end()) break ; else m_vMvrData.erase( iIter) ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::GetFixtureData( int nInd, string& sName, int& nId, Point3d& ptPos, double& dAngDeg) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico l'indice if ( nInd < 0 || nInd >= int( m_vFixData.size())) return false ; // recupero i dati sName = m_vFixData[nInd].sName ; nId = m_vFixData[nInd].nId ; ptPos = m_vFixData[nInd].ptPos ; dAngDeg = m_vFixData[nInd].dAng ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetMoveRawData( int nInd, int& nRawId, int& nType, Point3d& ptPos, int& nFlag) const { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // verifico l'indice if ( nInd < 0 || nInd >= int( m_vMvrData.size())) return false ; // recupero i dati nRawId = m_vMvrData[nInd].nRawId ; nType = m_vMvrData[nInd].nType ; ptPos = m_vMvrData[nInd].ptP ; nFlag = m_vMvrData[nInd].nFlag ; return true ; } //---------------------------------------------------------------------------- bool Disposition::SpecialApply( bool bRecalc) { // reset m_sHead.empty() ; m_nExit = 0 ; m_nShifts = 0 ; // verifico tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // recupero la macchina corrente Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr) return false ; // costanti static const string EMC_VAR = "EMC" ; // tabella variabili locali per calcolo static const string EVAR_TABNAME = ".TABNAME" ; // IN (string) nome della tavola macchina static const string EVAR_DISPID = ".DISPID" ; // IN (int) identificativo della disposizione static const string EVAR_ERROR = ".ERR" ; // OUT (int) codice di errore ( 0 = ok) static const string EVAR_HEAD = ".HEAD" ; // OUT (string) nome della testa static const string EVAR_EXIT = ".EXIT" ; // OUT (int) indice dell'uscita static const string EVAR_SHIFTS = ".SHIFTS" ; // OUT (int) numero di movimenti eseguiti static const string EVAR_SBH = ".SBH" ; // OUT (bool) flag presenza operazioni manuali static const string ON_SPECIAL_APPLY = "OnSpecialApplyDisposition" ; // eseguo l'azione if ( pMch->LuaExistsFunction( ON_SPECIAL_APPLY)) { bool bOk = true ; int nErr = 99 ; // imposto valori parametri bOk = bOk && pMch->LuaCreateGlobTable( EMC_VAR) ; bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_TABNAME, m_sTabName) ; bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_DISPID, m_nOwnerId) ; // eseguo bOk = bOk && pMch->LuaCallFunction( ON_SPECIAL_APPLY) ; // recupero valori parametri bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ; bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_HEAD, m_sHead) ; bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_EXIT, m_nExit) ; bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_SHIFTS, m_nShifts) ; bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_SBH, m_bSomeByHand) ; bOk = bOk && pMch->LuaResetGlobVar( EMC_VAR) ; // segnalo errori if ( nErr != 0) { bOk = false ; string sOut = " Error in " + ON_SPECIAL_APPLY + " (" + ToString( nErr) + ")" ; LOG_INFO( GetEMkLogger(), sOut.c_str()) } // se disposizione vuota, esco if ( m_nShifts == 0) return bOk ; // calcolo assi macchina string sHint = "" ; bOk = bOk && CalculateAxesValues( sHint) ; // gestione movimenti all'inizio di ogni singolo percorso di lavorazione e alla fine di tutti bOk = bOk && AdjustStartEndMovements() ; return bOk ; } else return true ; } //---------------------------------------------------------------------------- bool Disposition::GetToolData( string& sName, string& sHead, int& nExit) const { sName = "" ; sHead = m_sHead ; nExit = m_nExit ; return true ; } //---------------------------------------------------------------------------- const string& Disposition::GetToolName( void) const { static string sDummy = "" ; return sDummy ; } //---------------------------------------------------------------------------- const string& Disposition::GetHeadName( void) const { return m_sHead ; } //---------------------------------------------------------------------------- int Disposition::GetExitNbr( void) const { return m_nExit ; } //---------------------------------------------------------------------------- const string& Disposition::GetToolTcPos( void) const { static string sDummy = "" ; return sDummy ; } //---------------------------------------------------------------------------- bool Disposition:: NeedPrevHome( void) const { return ( IsEmpty() || m_bSomeByHand) ; }