//---------------------------------------------------------------------------- // 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 "OperationConst.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 ; //------------------------------ Errors -------------------------------------- // 2001 = "Error adding fixture xx" // 2002 = "Error placing fixture xx" // 2003 = "Error in MoveToCornerRawPart xx" // 2004 = "Error in MoveToCenterRawPart xx" // 2005 = "Error in ApplyRotationToRawPart xx" // 2006 = "Error in OnSpecialApplyDisposition (xxx)" // 2007 = "Error in Disposition : axes values not calculable" // 2008 = "Error in Disposition : outstroke xxx" // 2009 = "Error in Disposition : link movements not calculable" // 2010 = "Error in Disposition : link outstroke xxx" // 2051 = "Table Ref1 changed : (xyz) -> (XYZ)" // 2052 = "Warning in Disposition : No shifts" //---------------------------------------------------------------------------- static string DIS_TABLE = "Tab" ; static string DIS_PHASE = "Ph" ; static string DIS_REF1 = "Ref1" ; static string DIS_AREA1 = "Area1" ; static string DIS_FXD_TOT = "FxT" ; static string DIS_FXD_NAME = "FxN" ; static string DIS_FXD_POS = "FxP" ; static string DIS_FXD_ANG = "FxA" ; static string DIS_FXD_MOV = "FxM" ; static string DIS_MVD_TOT = "MvT" ; static string DIS_MVD_ID = "MvI" ; static string DIS_MVD_TYPE = "MvT" ; static string DIS_MVD_PNT = "MvP" ; static string DIS_MVD_ANG = "MvA" ; static string DIS_MVD_FLAG = "MvF" ; static string DIS_NUM = "NUM" ; static string DIS_HEAD = "Head" ; static string DIS_EXIT = "Exit" ; static string DIS_SOMEBYHAND = "Sbh" ; static string DIS_TCPOS = "TcPos" ; static string DIS_AREA1_OFFS = "Area1Offs" ; //---------------------------------------------------------------------------- static double DISP_BOX_TOL = - 0.5 ; //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_DISP), 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_dAreaOffset = m_dAreaOffset ; 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_sTcPos = m_sTcPos ; pDisp->m_nStatus = m_nStatus ; 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 += DIS_TABLE + EQUAL + m_sTabName + ( m_bTabOk ? " (ok)" : " (to verify)") + szNewLine ; sOut += DIS_PHASE + EQUAL + ToString( m_nPhase) + szNewLine ; sOut += DIS_REF1 + EQUAL + "(" + ToString( m_ptRef1, 3) + ")" + szNewLine ; sOut += DIS_AREA1 + EQUAL + "(" + ToString( m_b3Area1, 3) + ")" + szNewLine ; sOut += DIS_AREA1_OFFS + EQUAL + "(" + ToString( m_dAreaOffset) + ")" + 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 += DIS_NUM + EQUAL + ToString( m_nShifts) + szNewLine ; sOut += DIS_HEAD + EQUAL + m_sHead + szNewLine ; sOut += DIS_EXIT + EQUAL + ToString( m_nExit) + szNewLine ; sOut += DIS_TCPOS + EQUAL + m_sTcPos + szNewLine ; sOut += DIS_SOMEBYHAND + EQUAL + ToString( m_bSomeByHand) + szNewLine ; sOut += KEY_STAT + EQUAL + ToString( m_nStatus) + szNewLine ; return true ; } //---------------------------------------------------------------------------- bool Disposition::Save( int nBaseId, 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 = 7 ; 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 ; if ( ! SetVal( DIS_TCPOS, m_sTcPos, vString[++k])) return false ; if ( ! SetVal( DIS_AREA1_OFFS, m_dAreaOffset, vString[++k])) return false ; if ( ! SetVal( KEY_STAT, m_nStatus, 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 ; } if ( k + 1 < int( vString.size())) { if ( ! GetVal( vString[++k], DIS_TCPOS, m_sTcPos)) return false ; } if ( k + 1 < int( vString.size())) { if ( ! GetVal( vString[++k], DIS_AREA1_OFFS, m_dAreaOffset)) return false ; } if ( k + 1 < int( vString.size())) { if ( ! GetVal( vString[++k], KEY_STAT, m_nStatus)) return false ; } return true ; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- Disposition::Disposition( void) : m_bTabOk( false), m_nExit( 0), m_nStatus( MCH_ST_TO_VERIFY), m_nShifts( 0), m_bSomeByHand( false), m_dAreaOffset({{0,0,0,0}}) { } //---------------------------------------------------------------------------- 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 sInfo = "Table Ref1 changed : (" + ToString( ptPrevRef1) + ") -> (" + ToString( m_ptRef1) +")" ; m_pMchMgr->SetWarning( 2051, sInfo) ; } // salvo il nome e dichiaro tavola verificata m_sTabName = sTable ; m_bTabOk = true ; return true ; } //---------------------------------------------------------------------------- bool Disposition::SetAreaOffset( double dOffsXP, double dOffsYP, double dOffsXM, double dOffsYM) { m_dAreaOffset[0] = max( 0.0, dOffsXP) ; m_dAreaOffset[1] = max( 0.0, dOffsYP) ; m_dAreaOffset[2] = max( 0.0, dOffsXM) ; m_dAreaOffset[3] = max( 0.0, dOffsYM) ; return true ; } //---------------------------------------------------------------------------- bool Disposition::ResetAreaOffset( void) { m_dAreaOffset[0] = 0.0 ; m_dAreaOffset[1] = 0.0 ; m_dAreaOffset[2] = 0.0 ; m_dAreaOffset[3] = 0.0 ; 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::GetTableAreaOffset1( BBox3d& b3AreaOffs1) 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 con offset b3AreaOffs1 = BBox3d( m_b3Area1.GetMin() - Vector3d( m_dAreaOffset[2], m_dAreaOffset[3], 0), m_b3Area1.GetMax() + Vector3d( m_dAreaOffset[0], m_dAreaOffset[1], 0)) ; return true ; } //---------------------------------------------------------------------------- bool Disposition::Apply( bool bVerifyTab) { // verifico tavola if ( ( ! m_bTabOk || bVerifyTab) && ! SetTable( m_sTabName)) return false ; bool bOk = true ; // aggiornamento sottopezzi for ( auto& FixData : m_vFixData) { // se sottopezzo da caricare if ( FixData.nId == GDB_ID_NULL) { int nId = AddFixture( FixData.sName, GDB_ID_NULL, FixData.ptPos, FixData.dAng, FixData.dMov, false) ; if ( nId == GDB_ID_NULL) { string sOut = "Error adding fixture " + FixData.sName ; m_pMchMgr->SetLastError( 2001, sOut) ; bOk = false ; } 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) ; m_pMchMgr->SetLastError( 2002, sOut) ; bOk = false ; } } } // 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, false)) { string sOut = "Error in MoveToCornerRawPart " + ToString( vMvrData.nRawId) ; m_pMchMgr->SetLastError( 2003, sOut) ; bOk = false ; } break ; case MoveRawData::CEN : if ( ! MoveToCenterRawPart( vMvrData.nRawId, vMvrData.ptP, vMvrData.nFlag, false, false)) { string sOut = "Error in MoveToCenterRawPart " + ToString( vMvrData.nRawId) ; m_pMchMgr->SetLastError( 2004, sOut) ; bOk = false ; } break ; case MoveRawData::ROT : if ( ! ApplyRotationToRawPart( vMvrData.nRawId, vMvrData.ptP.x, vMvrData.ptP.y, vMvrData.ptP.z, false)) { string sOut = "Error in ApplyRotationToRawPart " + ToString( vMvrData.nRawId) ; m_pMchMgr->SetLastError( 2005, sOut) ; bOk = false ; } break ; } } return bOk ; } //---------------------------------------------------------------------------- bool Disposition::IsInTable( const Point3d& ptP) { if ( m_b3Area1.IsEmpty()) return false ; BBox3d b3AllArea( m_b3Area1.GetMin() - Vector3d( m_dAreaOffset[2], m_dAreaOffset[3], 0), m_b3Area1.GetMax() + Vector3d( m_dAreaOffset[0], m_dAreaOffset[1], 0)) ; return b3AllArea.EnclosesXY( ptP) ; } //---------------------------------------------------------------------------- bool Disposition::IsInTable( const BBox3d& b3B) { if ( m_b3Area1.IsEmpty()) return false ; BBox3d b3AllArea( m_b3Area1.GetMin() - Vector3d( m_dAreaOffset[2], m_dAreaOffset[3], 0), m_b3Area1.GetMax() + Vector3d( m_dAreaOffset[0], m_dAreaOffset[1], 0)) ; return b3AllArea.EnclosesXY( b3B) ; } //---------------------------------------------------------------------------- int Disposition::AddFixture( const string& sName, int nId, 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 ( ! IsInTable( m_ptRef1 + ptPos)) return GDB_ID_NULL ; // Ricerca int nFixtId = GDB_ID_NULL ; // Se già identificata if ( nId != GDB_ID_NULL) { if ( m_pMchMgr->IsUnusedFixture( nId, m_nPhase)) { nFixtId = nId ; // 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) ; } else return GDB_ID_NULL ; } // altrimenti else { // Nome tutto maiuscolo string sMyName = sName ; ToUpper( sMyName) ; // Se recuperabile dal gruppo dei bloccaggi 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() ; // recupero eventuale spostamento corrente della tavola Vector3d vtDelta1 ; Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr || ! pMch->GetCurrTableDeltaRef1( vtDelta1)) return false ; // la muovo nella posizione voluta Vector3d vtMove = ( m_ptRef1 + vtDelta1 + ptPos) - ORIG ; m_pGeomDB->TranslateGlob( nFixtId, vtMove) ; // la ruoto if ( abs( dAngDeg) > EPS_ANG_SMALL) m_pGeomDB->RotateGroup( nFixtId, ORIG, Z_AX, dAngDeg) ; // recupero ingombro sottopezzo (rimpicciolisco un poco per tolleranza) BBox3d b3Fixt ; if ( m_pGeomDB == nullptr || ! m_pGeomDB->GetGlobalBBox( nFixtId, b3Fixt)) return false ; b3Fixt.Expand( DISP_BOX_TOL) ; // verifico che la posizione finale sia nell'area della tavola (espressa in posizione 0) b3Fixt.Translate( - vtDelta1) ; if ( ! IsInTable( b3Fixt)) { RemoveFixture( nFixtId) ; return GDB_ID_NULL ; } // 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) { Vector3d vtDir = Z_AX ; m_pGeomDB->GetInfo( nMobId, FXT_MOB_MOVEDIR, vtDir) ; m_pGeomDB->TranslateGroup( nMobId, (dMov - dCurrVal) * vtDir) ; m_pGeomDB->SetInfo( nMobId, FXT_MOB_CPOS, dMov) ; } } // se da aggiungere alla lista if ( bAddToList) { m_vFixData.emplace_back( sName, nFixtId, ptPos, dAngDeg, dMov) ; m_nStatus |= MCH_ST_GEO_MODIF ; } 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->VerifyFixtureInGroup( 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->VerifyFixtureInGroup( 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->VerifyFixtureInGroup( nId, false)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // recupero eventuale spostamento corrente della tavola Vector3d vtDelta1 ; Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr || ! pMch->GetCurrTableDeltaRef1( vtDelta1)) return false ; // recupero ingombro sottopezzo BBox3d b3Fixt ; if ( m_pGeomDB == nullptr || ! m_pGeomDB->GetGlobalBBox( nId, b3Fixt)) return false ; b3Fixt.Expand( DISP_BOX_TOL) ; // verifico che la posizione finale sia nell'area della tavola (espressa in posizione 0) b3Fixt.Translate( vtMove - vtDelta1) ; if ( ! IsInTable( b3Fixt)) 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 ; } } // imposto stato a modificato m_nStatus |= MCH_ST_PARAM_MODIF ; return true ; } //---------------------------------------------------------------------------- bool Disposition::RotateFixture( int nId, double dDeltaAngDeg) { // verifica validità sottopezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixtureInGroup( 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 ; } } // imposto stato a modificato m_nStatus |= MCH_ST_PARAM_MODIF ; return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveFixtureMobile( int nId, double dDeltaMov) { // verifica validità sottopezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixtureInGroup( 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) { Vector3d vtDir = Z_AX ; m_pGeomDB->GetInfo( nMobId, FXT_MOB_MOVEDIR, vtDir) ; m_pGeomDB->TranslateGroup( nMobId, dDeltaMov * vtDir) ; 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 ; } } // imposto stato a modificato m_nStatus |= MCH_ST_PARAM_MODIF ; return true ; } //---------------------------------------------------------------------------- bool Disposition::PlaceFixture( int nId, const Point3d& ptPos, double dAngDeg, double dMov) { // verifica validità sottopezzo if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixtureInGroup( nId, false)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // recupero ingombro sottopezzo BBox3d b3Fixt ; if ( m_pGeomDB == nullptr || ! m_pGeomDB->GetGlobalBBox( nId, b3Fixt)) return false ; b3Fixt.Expand( DISP_BOX_TOL) ; // recupero riferimento sottopezzo Frame3d frFixt ; m_pGeomDB->GetGroupGlobFrame( nId, frFixt) ; // verifico che la posizione sia nell'area della tavola b3Fixt.Translate( m_ptRef1 + ptPos - frFixt.Orig()) ; if ( ! IsInTable( b3Fixt)) return false ; // aggiorno visualizzazione m_pGeomDB->SetStatus( nId, GDB_ST_ON) ; // resetto il riferimento del gruppo Frame3d* pfrFixt = m_pGeomDB->GetGroupFrame( nId) ; pfrFixt->Reset() ; // recupero eventuale spostamento corrente della tavola Vector3d vtDelta1 ; Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr || ! pMch->GetCurrTableDeltaRef1( vtDelta1)) return false ; // lo muovo nella posizione voluta Vector3d vtMove = ( m_ptRef1 + vtDelta1 + ptPos) - ORIG ; m_pGeomDB->TranslateGlob( nId, vtMove) ; // lo ruoto if ( abs( 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) { Vector3d vtDir = Z_AX ; m_pGeomDB->GetInfo( nMobId, FXT_MOB_MOVEDIR, vtDir) ; m_pGeomDB->TranslateGroup( nMobId, ( dMov - dCurrVal) * vtDir) ; 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->VerifyFixtureInGroup( nId, false)) return false ; // verifico aggiornamento tavola if ( ! m_bTabOk && ! SetTable( m_sTabName)) return false ; // dichiaro l'oggetto non più usato dalla fase e lo nascondo 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) ; } m_pGeomDB->SetStatus( nId, GDB_ST_OFF) ; // 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) ; } // imposto stato a modificato m_nStatus |= MCH_ST_GEO_MODIF ; return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveToCornerRawPart( int nRawId, const Point3d& ptP, int nFlag, bool bAddToList, bool bVerify) { // 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 ; } // se richiesto, verifico se il grezzo nella posizione finale sarà nella tavola b3Raw.Translate( vtMove) ; if ( bVerify && ! IsInTable( 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) { InsertMoveInfoInList( nRawId, MoveRawData::COR, ptP, nFlag) ; // imposto stato a modificato m_nStatus |= MCH_ST_PARAM_MODIF ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::MoveToCenterRawPart( int nRawId, const Point3d& ptP, int nFlag, bool bAddToList, bool bVerify) { // 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 ; } // se richiesto, verifico se il grezzo nella posizione finale sarà nella tavola b3Raw.Translate( vtMove) ; if ( bVerify && ! IsInTable( 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) { InsertMoveInfoInList( nRawId, MoveRawData::CEN, ptP, nFlag) ; // imposto stato a modificato m_nStatus |= MCH_ST_PARAM_MODIF ; } 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 ; // cerco il movimento di traslazione assoluto di questo grezzo (per sicurezza cerco l'ultimo) auto rTras = find_if( m_vMvrData.rbegin(), m_vMvrData.rend(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; // se non c'è non posso fare un movimento incrementale if ( rTras == m_vMvrData.rend()) 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 (espressa in posizione 0) b3Raw.Translate( vtMove - vtDelta1) ; if ( ! IsInTable( b3Raw)) return false ; // eseguo traslazione in globale m_pGeomDB->TranslateGlob( nRawId, vtMove) ; // aggiorno comando di movimento rTras->ptP += vtMove ; // imposto stato a modificato m_nStatus |= MCH_ST_PARAM_MODIF ; 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 ; // recupero il solido int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; // recupero box originale del grezzo (solo il solido ovviamente) BBox3d b3OriRaw ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3OriRaw)) 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) ; // cerco eventuale traslazione di questo grezzo auto iTras = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; // Se c'è traslazione if ( iTras != m_vMvrData.end()) { // determino il box del grezzo (solo il solido ovviamente) BBox3d b3Raw ; if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw)) return false ; // determino la traslazione correttiva da apportare Vector3d vtCorr ; if ( iTras->nType == MoveRawData::COR) { switch ( iTras->nFlag) { case MCH_CR_TL : vtCorr = Vector3d( b3Raw.GetMin().x - b3OriRaw.GetMin().x, b3Raw.GetMax().y - b3OriRaw.GetMax().y, b3Raw.GetMin().z - b3OriRaw.GetMin().z) ; break ; case MCH_CR_TR : vtCorr = Vector3d( b3Raw.GetMax().x - b3OriRaw.GetMax().x, b3Raw.GetMax().y - b3OriRaw.GetMax().y, b3Raw.GetMin().z - b3OriRaw.GetMin().z) ; break ; default : // RPCP_BL vtCorr = Vector3d( b3Raw.GetMin().x - b3OriRaw.GetMin().x, b3Raw.GetMin().y - b3OriRaw.GetMin().y, b3Raw.GetMin().z - b3OriRaw.GetMin().z) ; break ; case MCH_CR_BR : vtCorr = Vector3d( b3Raw.GetMax().x - b3OriRaw.GetMax().x, b3Raw.GetMin().y - b3OriRaw.GetMin().y, b3Raw.GetMin().z - b3OriRaw.GetMin().z) ; break ; } } else { Point3d ptOriCen ; b3OriRaw.GetCenter( ptOriCen) ; Point3d ptCen ; b3Raw.GetCenter( ptCen) ; switch ( iTras->nFlag) { case MCH_CE_TC : vtCorr = Vector3d( ptCen.x - ptOriCen.x, b3Raw.GetMax().y - b3OriRaw.GetMax().y, ptCen.z - ptOriCen.z) ; break ; default : // RPCE_ML vtCorr = Vector3d( b3Raw.GetMin().x - b3OriRaw.GetMin().x, ptCen.y - ptOriCen.y, ptCen.z - ptOriCen.z) ; break ; case MCH_CE_MR : vtCorr = Vector3d( b3Raw.GetMax().x - b3OriRaw.GetMax().x, ptCen.y - ptOriCen.y, ptCen.z - ptOriCen.z) ; break ; case MCH_CE_BC : vtCorr = Vector3d( ptCen.x - ptOriCen.x, b3Raw.GetMin().y - b3OriRaw.GetMin().y, ptCen.z - ptOriCen.z) ; break ; case MCH_CE_MC : vtCorr = Vector3d( ptCen.x - ptOriCen.x, ptCen.y - ptOriCen.y, b3Raw.GetMin().z - b3OriRaw.GetMin().z) ; break ; } } // 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 (espressa in posizione 0) b3Raw.Translate( - vtDelta1) ; if ( ! IsInTable( b3Raw)) { m_pGeomDB->RotateGlob( nRawId, ptAx, vtAx, - dAngRotDeg) ; return false ; } // modifico valore traslazione che verrà spostata dopo rotazione iTras->ptP += vtCorr ; // aggiungo o modifico nella lista InsertMoveInfoInList( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ; } // altrimenti else { // aggiungo o modifico nella lista InsertMoveInfoInList( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ; } // imposto stato a modificato m_nStatus |= MCH_ST_PARAM_MODIF ; return true ; } //---------------------------------------------------------------------------- bool Disposition::ApplyRotationToRawPart( int nRawId, double dAngCDeg, double dAngADeg, double dAngC1Deg, bool bAddToList) { // 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) ; // se da aggiungere alla lista if ( bAddToList) { // non ci sono problemi di compensazione della traslazione perchè già processata precedentemente in RotateRawPart InsertMoveInfoInList( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ; // imposto stato a modificato m_nStatus |= MCH_ST_PARAM_MODIF ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::InsertMoveInfoInList( int nRawId, int nType, const Point3d& ptP, int nFlag) { // verifico il tipo if ( nType != MoveRawData::COR && nType != MoveRawData::CEN && nType != MoveRawData::ROT) return false ; // cerco traslazione di questo grezzo auto iTras = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && ( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ; // cerco rotazione di questo grezzo auto iRot = find_if( m_vMvrData.begin(), m_vMvrData.end(), [ nRawId]( const MoveRawData& Mrv) { return ( Mrv.nRawId == nRawId && Mrv.nType == MoveRawData::ROT) ; }) ; // entrambi presenti if ( iTras != m_vMvrData.end() && iRot != m_vMvrData.end()) { // se traslazione precede rotazione, li scambio come contenuto e come iteratori if ( iTras < iRot) { swap( *iTras, *iRot) ; swap( iTras, iRot) ; } // se inserimento traslazione if ( nType != MoveRawData::ROT) *iTras = MoveRawData( nRawId, nType, ptP, nFlag) ; // altrimenti else *iRot = MoveRawData( nRawId, nType, ptP, nFlag) ; } // presente solo traslazione else if ( iTras != m_vMvrData.end()) { // se inserimento traslazione, la modifico if ( nType != MoveRawData::ROT) *iTras = MoveRawData( nRawId, nType, ptP, nFlag) ; // altrimenti inserisco rotazione subito prima della traslazione else m_vMvrData.emplace( iTras, nRawId, nType, ptP, nFlag) ; } // presente solo rotazione else if ( iRot != m_vMvrData.end()) { // se inserimento traslazione, la inserisco subito dopo la rotazione if ( nType != MoveRawData::ROT) m_vMvrData.emplace( iRot + 1, nRawId, nType, ptP, nFlag) ; // altrimenti modifico la rotazione else *iRot = MoveRawData( nRawId, nType, ptP, nFlag) ; } // assenti else { // inserisco alla fine m_vMvrData.emplace_back( nRawId, nType, ptP, nFlag) ; } 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) ; } // imposto stato a modificato m_nStatus |= MCH_ST_GEO_MODIF ; return true ; } //---------------------------------------------------------------------------- bool Disposition::GetFixtureData( int nInd, string& sName, int& nId, Point3d& ptPos, double& dAngDeg, double& dMov) 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 ; dMov = m_vFixData[nInd].dMov ; 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 string sCurrHead = m_sHead ; m_sHead.clear() ; int nCurrExit = m_nExit ; m_nExit = 0 ; int nCurrShifts = m_nShifts ; m_nShifts = 0 ; bool bCurrSomeByHand = m_bSomeByHand ; m_bSomeByHand = false ; string sCurrTcPos = m_sTcPos ; m_sTcPos.clear() ; // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // recupero la macchina corrente Machine* pMch = m_pMchMgr->GetCurrMachine() ; if ( pMch == nullptr) return false ; // se non esiste la funzione, non devo fare alcunché static const string ON_SPECIAL_APPLY = "OnSpecialApplyDisposition" ; if ( ! pMch->LuaExistsFunction( ON_SPECIAL_APPLY)) { m_nStatus = MCH_ST_OK ; return true ; } // verifico se necessario continuare nell'aggiornamento if ( ! bRecalc && m_nStatus == MCH_ST_OK) { m_sHead = sCurrHead ; m_nExit = nCurrExit ; m_nShifts = nCurrShifts ; m_bSomeByHand = bCurrSomeByHand ; m_sTcPos = sCurrTcPos ; LOG_DBG_INFO( GetEMkLogger(), "Disposition postapply skipped : status already ok") ; return true ; } m_nStatus = MCH_ST_TO_VERIFY ; // 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_PHASE = ".PHASE" ; // IN (int) indice fase 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_TCPOS = ".TCPOS" ; // OUT (string) nome della posizione nel TC static const string EVAR_SHIFTS = ".SHIFTS" ; // OUT (int) numero di movimenti eseguiti static const string EVAR_SBH = ".SBH" ; // OUT (bool) flag presenza operazioni manuali // eseguo l'azione bool bOk = true ; int nErr = 99 ; // verifico tavola bOk = ( m_bTabOk || SetTable( m_sTabName)) ; // 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) ; bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_PHASE, GetPhase()) ; // eseguo bOk = bOk && pMch->LuaCallFunction( ON_SPECIAL_APPLY, false) ; // recupero valori parametri obbligatori 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) ; // recupero valori parametri opzionali if ( bOk) pMch->LuaGetGlobVar( EMC_VAR + EVAR_TCPOS, m_sTcPos) ; // reset bOk = bOk && pMch->LuaResetGlobVar( EMC_VAR) ; // segnalo errori ed esco if ( ! bOk || nErr != 0) { m_nShifts = - 1 ; string sOut = " Error in " + ON_SPECIAL_APPLY + " (" + ToString( nErr) + ")" ; m_pMchMgr->SetLastError( 2006, sOut) ; return false ; } // eseguo aggiornamento assi macchina e collegamento con operazione precedente if ( ! SpecialUpdate()) return false ; // aggiorno stato m_nStatus = MCH_ST_OK ; return true ; } //---------------------------------------------------------------------------- bool Disposition::SpecialUpdate( void) { // verifico MachMgr e GeomDB if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; // se disposizione vuota, esco if ( m_nShifts <= 0) { if ( m_nShifts < 0) m_pMchMgr->SetWarning( 2052, "Warning in Disposition : No shifts") ; return true ; } // calcolo assi macchina if ( ! CalculateAxesValues( "")) { string sInfo = m_pMchMgr->GetOutstrokeInfo() ; if ( sInfo.empty()) m_pMchMgr->SetLastError( 2007, "Error in Disposition : axes values not calculable") ; else m_pMchMgr->SetLastError( 2008, "Error in Disposition : outstroke ") ; return false ; } // gestione movimenti all'inizio di ogni singolo percorso di lavorazione e alla fine di tutti if ( ! AdjustStartEndMovements()) { string sInfo = m_pMchMgr->GetOutstrokeInfo() ; if ( sInfo.empty()) m_pMchMgr->SetLastError( 2009, "Error in Disposition : link movements not calculable") ; else m_pMchMgr->SetLastError( 2010, "Error in Disposition : link outstroke ") ; return false ; } return true ; } //---------------------------------------------------------------------------- bool Disposition::GetToolData( string& sName, string& sHead, int& nExit, string& sTcPos) const { sName = "" ; sHead = m_sHead ; nExit = m_nExit ; sTcPos = m_sTcPos ; 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 { return m_sTcPos ; } //---------------------------------------------------------------------------- bool Disposition:: NeedPrevHome( void) const { return ( m_bSomeByHand) ; }