diff --git a/MachMgr.h b/MachMgr.h index 55e69ea..356e69c 100644 --- a/MachMgr.h +++ b/MachMgr.h @@ -456,6 +456,8 @@ class MachMgr : public IMachMgr int GetCurrRotAxes( void) const ; bool GetAllCurrAxesHomePos( DBLVECTOR& vAxHomeVal) const ; bool GetCurrAxisHomePos( int nInd, double& dHome) const ; + bool GetCurrAxisMax( int nInd, double& dHome) const ; + bool GetCurrAxisMin( int nInd, double& dHome) const ; const Frame3d& GetCurrLinAxesFrame( void) const ; bool GetCurrIsCenter( void) const ; bool GetCurrIsRobot( void) const ; diff --git a/MachMgrMachines.cpp b/MachMgrMachines.cpp index 2151456..c507b40 100644 --- a/MachMgrMachines.cpp +++ b/MachMgrMachines.cpp @@ -711,6 +711,22 @@ MachMgr::GetCurrAxisHomePos( int nInd, double& dHome) const return ( ( pMch != nullptr) ? pMch->GetCurrAxisHomePos( nInd, dHome) : false) ; } +//---------------------------------------------------------------------------- +bool +MachMgr::GetCurrAxisMax( int nInd, double& dMax) const +{ + Machine* pMch = GetCurrMachine() ; + return ( ( pMch != nullptr) ? pMch->GetCurrAxisMax( nInd, dMax) : false) ; +} + +//---------------------------------------------------------------------------- +bool +MachMgr::GetCurrAxisMin( int nInd, double& dMin) const +{ + Machine* pMch = GetCurrMachine() ; + return ( ( pMch != nullptr) ? pMch->GetCurrAxisMin( nInd, dMin) : false) ; +} + //---------------------------------------------------------------------------- const Frame3d& MachMgr::GetCurrLinAxesFrame( void) const diff --git a/Machine.cpp b/Machine.cpp index f361680..fc9e2ab 100644 --- a/Machine.cpp +++ b/Machine.cpp @@ -42,6 +42,7 @@ Machine::Machine( void) m_dExitMaxRotAdj = 10 * EPS_ANG_SMALL ; m_dAngDeltaMinForHome = INFINITO ; m_nMultiProcess = 0 ; + m_nNewLinkMgr = 0 ; m_nCalcTabId = GDB_ID_NULL ; m_nCalcHeadId = GDB_ID_NULL ; m_nCalcExitId = GDB_ID_NULL ; diff --git a/Machine.h b/Machine.h index 214dbfa..dcf644c 100644 --- a/Machine.h +++ b/Machine.h @@ -86,6 +86,8 @@ class Machine { return m_dAngDeltaMinForHome ; } bool GetMultiProcess( int nOpt = 1) const { return ( m_nMultiProcess >= nOpt) ; } + bool GetNewLinkMgr( int nOpt = 1) const + { return ( m_nNewLinkMgr >= nOpt) ; } bool LoadTool( const std::string& sHead, int nExit, const std::string& sTool) ; bool GetLoadedTool( const std::string& sHead, int nExit, std::string& sTool) const ; bool UnloadTool( const std::string& sHead, int nExit) ; @@ -176,7 +178,7 @@ class Machine bool VerifyAngleOutstroke( int nInd, double dAng) const ; bool VerifyOutstroke( double dX, double dY, double dZ, const DBLVECTOR& vAng, bool bClear, int& nStat) const ; bool ExistProtectedAreas( void) const ; - bool VerifyProtectedAreas( double dX, double dY, double dZ, const DBLVECTOR& vAng, int& nStat) ; + bool VerifyProtectedAreas( double dX, double dY, double dZ, const DBLVECTOR& vAng, bool bIsLink, int& nStat) ; bool VerifyOutstroke( const std::string& sAxName, double dVal) const ; std::string GetOutstrokeInfo( bool bMM = true) const ; void ResetOutstrokeInfo( void) const @@ -295,7 +297,8 @@ class Machine double m_dExitMaxAdjust ; // massimo aggiustamento uscita da geometria a descrizione cinematica double m_dExitMaxRotAdj ; // massima rotazione di aggiustamento uscita da geometria a descrizione cinematica double m_dAngDeltaMinForHome ; // minima differenza angolare da valore precedente per scegliere di stare vicino a home - int m_nMultiProcess ; // flag di macchina multi-processo con stima speciale prima di generazione e simulazione ad hoc + int m_nMultiProcess ; // codice di macchina multi-processo (con stima speciale e simulazione ad hoc) + int m_nNewLinkMgr ; // codice del nuovo gestore link tra lavorazioni (0=vecchio, 1=nuovo) INTVECTOR m_vLinkedRawParts ; // elenco dei grezzi agganciati a gruppi della macchina INTVECTOR m_vLinkedFixtures ; // elenco dei bloccaggi agganciati a gruppi della macchina INTVECTOR m_vLinkedParts ; // elenco dei pezzi agganciati a gruppi della macchina diff --git a/MachineCalc.cpp b/MachineCalc.cpp index f2f4e5b..adbdca4 100644 --- a/MachineCalc.cpp +++ b/MachineCalc.cpp @@ -48,6 +48,7 @@ static const string EVAR_R1 = ".R1" ; // (num) valore del pri static const string EVAR_R2 = ".R2" ; // (num) valore del secondo asse rotante static const string EVAR_R3 = ".R3" ; // (num) valore del terzo asse rotante static const string EVAR_R4 = ".R4" ; // (num) valore del quarto asse rotante +static const string EVAR_ISLINK = ".ISLINK" ; // (bool) flag per indicare controllo posizioni in un link static const string EVAR_ERROR = ".ERR" ; // OUT (int) codice di errore ( 0 = ok) static const string EVAR_STAT = ".STAT" ; // OUT (int) codice di stato ( 0 = ok) static const string EVAR_AUXINFO = ".AUXINFO" ; // OUT (string) stringa con info ausiliarie @@ -1718,7 +1719,7 @@ Machine::VerifyOutstroke( double dX, double dY, double dZ, const DBLVECTOR& vAng } // verifica delle aree protette if ( nStat == 0) - return const_cast( this)->VerifyProtectedAreas( dX, dY, dZ, vAng, nStat) ; + return const_cast( this)->VerifyProtectedAreas( dX, dY, dZ, vAng, false, nStat) ; return true ; } @@ -1732,7 +1733,7 @@ Machine::VerifyOutstroke( double dX, double dY, double dZ, const DBLVECTOR& vAng //---------------------------------------------------------------------------- bool -Machine::VerifyProtectedAreas( double dX, double dY, double dZ, const DBLVECTOR& vAng, int& nStat) +Machine::VerifyProtectedAreas( double dX, double dY, double dZ, const DBLVECTOR& vAng, bool bIsLink, int& nStat) { // se non esiste funzione gestione aree protette, non devo fare alcunchè if ( ! LuaExistsFunction( ON_VERIFY_PROTECTEDAREAS)) @@ -1756,6 +1757,7 @@ Machine::VerifyProtectedAreas( double dX, double dY, double dZ, const DBLVECTOR& bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_R3, vAng[2]) ; if ( vAng.size() >= 4) bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_R4, vAng[3]) ; + bOk = bOk && LuaSetGlobVar( EMC_VAR + EVAR_ISLINK, bIsLink) ; // chiamo funzione bOk = bOk && LuaCallFunction( ON_VERIFY_PROTECTEDAREAS) ; // recupero il risultato diff --git a/MachineLua.cpp b/MachineLua.cpp index c27e41f..dc69c1a 100644 --- a/MachineLua.cpp +++ b/MachineLua.cpp @@ -37,6 +37,7 @@ static const string FLD_EXITMAXADJUST = "ExitMaxAdjust" ; static const string FLD_EXITMAXROTADJ = "ExitMaxRotAdj" ; static const string FLD_ANGDELTAMINFORHOME = "AngDeltaMinForHome" ; static const string FLD_MULTIPROCESS = "MultiProcess" ; +static const string FLD_NEWLINKMGR = "NewLinkMgr" ; static const string FLD_NAME = "Name" ; static const string FLD_PARENT = "Parent" ; static const string FLD_GEO = "Geo" ; @@ -350,6 +351,10 @@ Machine::LuaEmtGeneral( lua_State* L) // lettura eventuale campo 'MultiProcess' dalla tabella (0=no, 1=si, 2=si con simulazione MP) int nMultiProcess = 0 ; LuaGetTabFieldParam( L, 1, FLD_MULTIPROCESS, nMultiProcess) ; + // lettura eventuale campo 'NewLinkMgr' dalla tabella (0=old, 1 =new) + int nNewLinkMgr = 0 ; + LuaGetTabFieldParam( L, 1, FLD_NEWLINKMGR, nNewLinkMgr) ; + // pulizia stack LuaClearStack( L) ; // info @@ -399,8 +404,10 @@ Machine::LuaEmtGeneral( lua_State* L) // imposto minima differenza angolare da posizione precedente per stare vivino a posizione home m_pMchLua->m_dAngDeltaMinForHome = dAngDeltaMinForHome ; - // imposto flag per macchina multiprocesso + // imposto codice per macchina multiprocesso m_pMchLua->m_nMultiProcess = nMultiProcess ; + // imposto codice per gestione link tra lavorazioni + m_pMchLua->m_nNewLinkMgr = nNewLinkMgr ; return 0 ; } diff --git a/Milling.cpp b/Milling.cpp index ece3158..212faff 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -2393,12 +2393,12 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo bool bSideStart = false ; if ( ! bGeomAboveStart) { bAhUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1 + vtWkTip, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; } else { bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1 + vtWkTip, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; } // se non sono sotto, verifico se posso allontanarmi nel piano lama (meglio se in orizzontale) @@ -2581,12 +2581,12 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo bool bSideEnd = false ; if ( ! bGeomAboveEnd) { bAhUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1 + vtWkTip, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( true), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; } else { bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1 + vtWkTip, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( true), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; } if ( ! bAhUnderEnd && ! bUhAboveEnd) { @@ -2768,7 +2768,7 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool bool bSideStart = false ; if ( ! bGeomAboveStart) { bUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; } @@ -2937,7 +2937,7 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool bool bSideEnd = false ; if ( ! bGeomAboveEnd) { bUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; } if ( ! bUnderEnd) { @@ -3237,12 +3237,12 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool bool bSideStart = false ; if ( ! bGeomAboveStart) { bAhUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; } else { bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; } // se non sono sotto, verifico se posso allontanarmi nel piano lama (meglio se in orizzontale) @@ -3428,12 +3428,12 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool bool bSideEnd = false ; if ( ! bGeomAboveEnd) { bAhUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; } else { bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation(), m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; } if ( ! bAhUnderEnd && ! bUhAboveEnd) { diff --git a/Operation.cpp b/Operation.cpp index bb895f1..9c8dbb2 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -2580,7 +2580,8 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr || m_pMchMgr->GetCurrMachine() == nullptr) return false ; - // recupero gruppo della geometria di lavorazione (Cutter Location) + + // recupero gruppo della geometria di lavorazione (Cutter Location) int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ; if ( nClId == GDB_ID_NULL) return false ; @@ -2601,10 +2602,17 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) if ( pPrevOp != nullptr && ! pPrevOp->IsEmpty()) sPrevTool = pPrevOp->GetToolName() ; + // flag nuova gestione collegamenti tra lavorazioni + bool bNewLink = m_pMchMgr->GetCurrMachine()->GetNewLinkMgr() ; + + // flag per CLIMB a inizio percorso già gestito + bool bClimbDone = false ; + // determino posizione precedente assi DBLVECTOR vAxVal ; bool bMaxZ = false ; - // se primo utensile o richiesto, uso la posizione home + + // *** Se primo utensile o richiesto, uso la posizione home if ( sPrevTool.empty() || NeedPrevHome()) { // imposto l'utensile per i calcoli macchina if ( ! m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) @@ -2614,8 +2622,19 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) return false ; // si parte da Z massima bMaxZ = true ; + // per nuova gestione collegamenti, verifica aree protette + if ( bVerifyPreviousLink && bNewLink && m_pMchMgr->GetCurrIsCenter()) { + // recupero posizione iniziale lavorazione + DBLVECTOR vAxIni ; + if ( ! GetInitialAxesValues( true, vAxIni)) + return false ; + // eseguo verifica + if ( ! ManageProtectedAreas( vAxVal, vAxIni, nullptr, this, bClimbDone)) + return false ; + } } - // se utensile non cambiato o su diversa uscita della stessa testa, uso posizione finale della lavorazione precedente + + // *** Se utensile non cambiato o su diversa uscita della stessa testa, uso posizione finale della lavorazione precedente else if ( ! ToolChangeNeeded( *pPrevOp, *this)) { // imposto l'utensile per i calcoli macchina if ( ! m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) @@ -2628,7 +2647,7 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) if ( ! pPrevOp->GetFinalAxesValues( false, vAxVal)) return false ; // elimino eventuali CLIMB già presenti - RemoveClimb( m_pGeomDB->GetFirstGroupInGroup( nClId)) ; + RemoveClimb() ; // recupero posizione iniziale lavorazione DBLVECTOR vAxIni ; if ( ! GetInitialAxesValues( false, vAxIni)) @@ -2637,7 +2656,7 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) if ( m_pMchMgr->GetCurrIsCenter()) { // recupero se ZHome è in basso bool bZHomeDown = GetZHomeDown() ; - // recupero quota di home in Z + // recupero quote home e max di Z double dHomeZ ; if ( ! m_pMchMgr->GetCurrAxisHomePos( 2, dHomeZ)) return false ; @@ -2645,13 +2664,13 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) double dDeltaZ = ( vAxIni[2] - vAxVal[2]) ; if ( ( ! bZHomeDown && dDeltaZ > 100 * EPS_SMALL && vAxIni[2] <= dHomeZ) || ( bZHomeDown && dDeltaZ < -100 * EPS_SMALL && vAxIni[2] >= dHomeZ)) { - if ( ! pPrevOp->AddRise( vAxVal, dDeltaZ, GDB_ID_NULL, bZHomeDown)) + if ( ! pPrevOp->AddRise( vAxVal, dDeltaZ)) return false ; // aggiorno quota in Z della posizione iniziale ( anche se verrà aggiornata solo in seguito) vAxIni[2] = vAxVal[2] ; } // Verifico non ci sia collisione a HomeZ - bool bToZmax = false ; + bool bToMaxZ = false ; bool bToMyHomeZ = false ; DBLVECTOR vAxVal2 = vAxVal ; vAxVal2[2] = dHomeZ ; DBLVECTOR vAxIni2 = vAxIni ; vAxIni2[2] = dHomeZ ; @@ -2670,10 +2689,10 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) bToMyHomeZ = true ; } else - bToZmax = true ; + bToMaxZ = true ; } else - bToZmax = true ; + bToMaxZ = true ; } // se altrimenti ammessa rotazione a Zmax e richiesta rotazione else if ( GetRotationAtZmax() && @@ -2706,11 +2725,11 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) // non devo fare alcunché } // se altrimenti richiesta risalita a Zmax - else if ( bToZmax || ForcedZmax( vAxVal, vAxIni, b3Raws)) { + else if ( bToMaxZ || ForcedZmax( vAxVal, vAxIni, b3Raws)) { // cancello eventuale risalita parziale della lavorazione precedente pPrevOp->RemoveRise() ; - // aggiungo risalita a Zmax - if ( ! pPrevOp->AddRise( vAxVal)) + // aggiungo risalita a HomeZ/MaxZ + if ( ! pPrevOp->AddRise( vAxVal, NAN, GDB_ID_NULL, ( bNewLink ? ( bZHomeDown ? -1 : +1) : 0))) return false ; // si parte da Z massima bMaxZ = true ; @@ -2771,42 +2790,15 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) pPrevOp->GetFinalAxesValues( false, vAxVal) ; // aggiungo risalita a Zsafe double dDelta = ( ! bZHomeDown ? max( dSafeZ - vAxVal[2], 0.) : min( dSafeZ - vAxVal[2], 0.)) ; - if ( ! pPrevOp->AddRise( vAxVal, dDelta, GDB_ID_NULL, bZHomeDown)) + if ( ! pPrevOp->AddRise( vAxVal, dDelta)) return false ; // aggiorno quota iniziale in Z vAxIni[2] = dSafeZ ; } } - // se ci sono aree protette... - if ( m_pMchMgr->GetCurrMachine()->ExistProtectedAreas()) { - // verifico se il collegamento le attraversa - const double PA_VERIF_LEN = 10 ; - Point3d ptStart( vAxVal[0], vAxVal[1], vAxVal[2]) ; - Point3d ptEnd( vAxIni[0], vAxIni[1], vAxIni[2]) ; - double dLen = DistXY( ptStart, ptEnd) ; - int nStep = int( dLen / PA_VERIF_LEN + 1) ; - bool bOutstroke = false ; - for ( int i = 1 ; i < nStep ; ++ i) { - Point3d ptCurr = Media( ptStart, ptEnd, double( i) / nStep) ; - int nStat = 0 ; - if ( ! m_pMchMgr->GetCurrMachine()->VerifyProtectedAreas( ptCurr.x, ptCurr.y, ptCurr.z, {}, nStat) || nStat != 0) { - bOutstroke = true ; - break ; - } - } - // in caso di attraversamento dell'area proibita - if ( bOutstroke) { - // chiamo funzione script OnSpecialRapidMove per avere nuovo punto intermedio - DBLVECTOR vAxNew ; - bool bModif = false ; - bool bOk = ( SpecialMoveRapid( vAxVal, vAxIni, vAxNew, bModif) && bModif) ; - // inserisco il nuovo punto alla fine della lavorazione precedente - if ( bOk) - vAxVal = vAxNew ; - if ( ! pPrevOp->AddSpecialRise( vAxVal, bOk)) - return false ; - } - } + // gestione eventuali aree protette + if ( ! ManageProtectedAreas( vAxVal, vAxIni, pPrevOp, this, bClimbDone)) + return false ; } // se robot else if ( m_pMchMgr->GetCurrIsRobot()) { @@ -2857,7 +2849,8 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) return false ; } } - // altrimenti aggiungo uscita per cambio utensile alla lavorazione precedente e parto da questa + + // *** Altrimenti aggiungo uscita per cambio utensile alla lavorazione precedente e parto da questa else { // imposto la lavorazione precedente come corrente m_pMchMgr->SetCurrMachining( pPrevOp->GetOwner()) ; @@ -2869,18 +2862,39 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) if ( ! pPrevOp->AddRise( vAxVal)) return false ; } - else { + // per nuova gestione collegamenti, verifica aree protette + if ( bVerifyPreviousLink && bNewLink && m_pMchMgr->GetCurrIsCenter()) { + // recupero posizione finale lavorazione + if ( ! GetFinalAxesValues( true, vAxVal)) + return false ; // recupero posizione home - if ( ! m_pMchMgr->GetAllCurrAxesHomePos( vAxVal)) + DBLVECTOR vAxIni ; + if ( ! m_pMchMgr->GetAllCurrAxesHomePos( vAxIni)) + return false ; + if ( ! ManageProtectedAreas( vAxVal, vAxIni, this, nullptr, bClimbDone)) return false ; } + // ripristino la lavorazione corrente m_pMchMgr->SetCurrMachining( GetOwner()) ; // imposto l'utensile per i calcoli macchina if ( ! m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) return false ; + // recupero posizione home + if ( ! m_pMchMgr->GetAllCurrAxesHomePos( vAxVal)) + return false ; // si parte da Z massima bMaxZ = true ; + // per nuova gestione collegamenti, verifica aree protette + if ( bVerifyPreviousLink && bNewLink && m_pMchMgr->GetCurrIsCenter()) { + // recupero posizione iniziale lavorazione + DBLVECTOR vAxIni ; + if ( ! GetInitialAxesValues( true, vAxIni)) + return false ; + // eseguo verifica + if ( ! ManageProtectedAreas( vAxVal, vAxIni, nullptr, this, bClimbDone)) + return false ; + } } // aggiusto l'inizio di ogni percorso di lavoro @@ -2889,8 +2903,8 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) int nClPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; while ( bOk && nClPathId != GDB_ID_NULL) { // se richiesta verifica collegamento con lavorazione precedente, sistemo inizio - if ( bVerifyPreviousLink) { - if ( ! AdjustOneStartMovement( nClPathId, nPrevClPathId, pPrevOp, vAxVal, bMaxZ)) + if ( bVerifyPreviousLink && ( ! bClimbDone || nPrevClPathId != GDB_ID_NULL)) { + if ( ! AdjustOneStartEndMovement( nClPathId, nPrevClPathId, pPrevOp, vAxVal, bMaxZ)) bOk = false ; } bMaxZ = false ; @@ -2904,8 +2918,20 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) pPrevOp = nullptr ; } - // aggiungo risalita finale + // Aggiungo risalita finale bOk = bOk && AddRise( vAxVal) ; + // per nuova gestione collegamenti, verifica aree protette + if ( bVerifyPreviousLink && bNewLink && m_pMchMgr->GetCurrIsCenter()) { + // recupero posizione finale lavorazione + if ( ! GetFinalAxesValues( true, vAxVal)) + return false ; + // recupero posizione home + DBLVECTOR vAxIni ; + if ( ! m_pMchMgr->GetAllCurrAxesHomePos( vAxIni)) + return false ; + if ( ! ManageProtectedAreas( vAxVal, vAxIni, this, nullptr, bClimbDone)) + return false ; + } // se ultima operazione o la successiva lo richiede, vado in home int nNextOpId = m_pMchMgr->GetNextActiveOperation( m_nOwnerId) ; @@ -2918,7 +2944,98 @@ Operation::AdjustStartEndMovements( bool bVerifyPreviousLink) //---------------------------------------------------------------------------- bool -Operation::AdjustOneStartMovement( int nClPathId, int nPrevClPathId, Operation* pPrevOp, const DBLVECTOR& vAxPrev, bool bMaxZ) +Operation::ManageProtectedAreas( const DBLVECTOR& vAxVal, const DBLVECTOR& vAxIni, Operation* pPrevOp, Operation* pNextOp, + bool& bClimbDone) +{ + // se non ci sono aree protette, esco subito. + if ( ! m_pMchMgr->GetCurrMachine()->ExistProtectedAreas()) + return true ; + + // flag nuova gestione collegamenti tra lavorazioni + bool bNewLink = m_pMchMgr->GetCurrMachine()->GetNewLinkMgr() ; + + // verifico se il collegamento le attraversa + const double PA_VERIF_LEN = 10 ; + Point3d ptStart( vAxVal[0], vAxVal[1], vAxVal[2]) ; + Point3d ptEnd( vAxIni[0], vAxIni[1], vAxIni[2]) ; + double dLen = DistXY( ptStart, ptEnd) ; + int nStep = int( dLen / PA_VERIF_LEN + 1) ; + bool bOutstroke = false ; + for ( int i = 0 ; i <= nStep ; ++ i) { + double dCoeff = double( i) / nStep ; + Point3d ptCurr = Media( ptStart, ptEnd, dCoeff) ; + DBLVECTOR vAng ; + int nRotAxisNum = int( vAxVal.size()) - 3 ; + if ( bNewLink && nRotAxisNum > 0) { + vAng.resize( nRotAxisNum) ; + for ( int j = 0 ; j < nRotAxisNum ; ++ j) + vAng[j] = ( 1 - dCoeff) * vAxVal[j+3] + dCoeff * vAxIni[j+3] ; + } + int nStat = 0 ; + if ( ! m_pMchMgr->GetCurrMachine()->VerifyProtectedAreas( ptCurr.x, ptCurr.y, ptCurr.z, vAng, true, nStat) || nStat != 0) { + bOutstroke = true ; + break ; + } + } + if ( ! bOutstroke) + return true ; + + // chiamo funzione script OnSpecialRapidMove per avere posizioni di movimento + int nLinkType = 0 + ( pPrevOp == nullptr ? 0 : 1) + ( pNextOp == nullptr ? 0 : 2) ; + POSVECTOR vPosNew ; + bool bModif = false ; + int nErase = 0 ; + bool bOk = ( SpecialMoveRapid( vAxVal, vAxIni, nLinkType, vPosNew, bModif, nErase) && bModif) ; + // se tutto bene, eseguo cancellazioni e einserimenti come richiesto + if ( bOk) { + // eventuali cancellazioni + if ( ( nErase & 1) != 0) { + if ( pPrevOp == nullptr) + return false ; + pPrevOp->RemoveRise() ; + } + if ( ( nErase & 2) != 0) { + if ( pNextOp == nullptr) + return false ; + pNextOp->RemoveClimb() ; + bClimbDone = true ; + } + // eventuali inserimenti + for ( const auto& PosNew : vPosNew) { + if ( PosNew.nSide == -1) { + if ( pPrevOp == nullptr) + return false ; + if ( ! pPrevOp->AddSpecialRise( PosNew.vAxis, true, GDB_ID_NULL, PosNew.nFlag, PosNew.nFlag2)) + return false ; + } + else { + if ( pNextOp == nullptr) + return false ; + if ( ! pNextOp->AddSpecialClimb( PosNew.vAxis, true, GDB_ID_NULL, PosNew.nFlag, PosNew.nFlag2)) + return false ; + } + } + } + // altrimenti eseguo inserimento con segnalazione di errore + else { + if ( pPrevOp != nullptr) { + if ( ! pPrevOp->AddSpecialRise( vAxVal, false)) + return false ; + } + else if ( pNextOp != nullptr) { + if ( ! pNextOp->AddSpecialClimb( vAxIni, false)) + return false ; + } + else + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Operation::AdjustOneStartEndMovement( int nClPathId, int nPrevClPathId, Operation* pPrevOp, const DBLVECTOR& vAxPrev, bool bMaxZ) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -2988,7 +3105,7 @@ Operation::AdjustOneStartMovement( int nClPathId, int nPrevClPathId, Operation* // se altrimenti robot else if ( m_pMchMgr->GetCurrIsRobot()) { // inserisco la posizione iniziale a Zmax - if ( ! AddRobotClimb( nEntId, -1)) + if ( ! AddRobotClimb( nEntId)) return false ; } } @@ -3050,12 +3167,12 @@ Operation::AdjustOneStartMovement( int nClPathId, int nPrevClPathId, Operation* DBLVECTOR vAxPrevNoRise ; pPrevOp->GetFinalAxesValues( false, vAxPrevNoRise) ; double dDelta = ( ! bZHomeDown ? max( dSafeZ - vAxPrevNoRise[2], 0.) : min( dSafeZ - vAxPrevNoRise[2], 0.)) ; - if ( ! pPrevOp->AddRise( vAxNew1, dDelta, GDB_ID_NULL, bZHomeDown)) + if ( ! pPrevOp->AddRise( vAxNew1, dDelta)) return false ; } else { double dDelta = ( ! bZHomeDown ? max( dSafeZ - vAxPrev[2], 0.) : min( dSafeZ - vAxPrev[2], 0.)) ; - if ( ! AddRise( vAxNew1, dDelta, nPrevClPathId, bZHomeDown)) + if ( ! AddRise( vAxNew1, dDelta, nPrevClPathId)) return false ; } // aggiungo posizione elevata prima dell'inizio del percorso corrente @@ -3107,7 +3224,7 @@ Operation::AdjustOneStartMovement( int nClPathId, int nPrevClPathId, Operation* // aggiungo risalita alla fine del precedente percorso DBLVECTOR vAxNew ; double dDelta = ( ! bZHomeDown ? max( vAxCurr[2] - vAxPrev[2], 0.) : min( vAxCurr[2] - vAxPrev[2], 0.)) ; - if ( ! AddRise( vAxNew, dDelta, nPrevClPathId, bZHomeDown)) + if ( ! AddRise( vAxNew, dDelta, nPrevClPathId)) return false ; } // altrimenti Z corrente minore della precedente @@ -3227,11 +3344,11 @@ Operation::AdjustOneStartMovement( int nClPathId, int nPrevClPathId, Operation* // eventuali risalite finali già eliminate dal chiamante // aggiungo risalita a Z max alla fine del percorso precedente DBLVECTOR vAxNew = vAxPrev ; - if ( ! AddRise( vAxNew, -1, nPrevClPathId)) + if ( ! AddRise( vAxNew, NAN, nPrevClPathId)) return false ; } // inserisco la posizione iniziale a Zmax in questo percorso - if ( ! AddRobotClimb( nEntId, -1)) + if ( ! AddRobotClimb( nEntId)) return false ; } } @@ -3259,12 +3376,83 @@ Operation::ToolChangeNeeded( const Operation& Op1, const Operation& Op2) const return true ; } +//---------------------------------------------------------------------------- +bool +Operation::AddSpecialClimb( const DBLVECTOR& vAxVal, bool bOk, int nClPathId, int nFlag, int nFlag2) +{ + if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) + return false ; + // recupero gruppo per geometria di lavorazione (Cutter Location) + int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_CL) ; + if ( nClId == GDB_ID_NULL) + return false ; + // se percorso CL specificato, verifico appartenga al gruppo sopra ricavato + if ( nClPathId != GDB_ID_NULL) { + if ( m_pGeomDB->GetParentId( nClPathId) != nClId) + return false ; + } + // altrimenti, recupero il primo percorso CL della operazione + else { + nClPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; + if ( nClPathId == GDB_ID_NULL) + return false ; + } + // recupero la prima entità del percorso + int nEntId = m_pGeomDB->GetFirstInGroup( nClPathId) ; + if ( nEntId == GDB_ID_NULL) + return false ; + // ne recupero i dati Cam + CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nEntId)) ; + if ( pCamData == nullptr) + return false ; + // creo oggetto punto per DB geometrico + PtrOwner pGP( CreateGeoPoint3d()) ; + if ( IsNull( pGP)) + return false ; + // assegno le coordinate del punto + pGP->Set( pCamData->GetEndPoint()) ; + // inserisco l'oggetto nel DB geometrico all'inizio del percorso + int nId = m_pGeomDB->InsertGeoObj( GDB_ID_NULL, nEntId, GDB_BEFORE, Release( pGP)) ; + if ( nId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nId, MCH_CL_CLIMB) ; + // creo oggetto dati Cam da associare al punto + PtrOwner pCam( pCamData->Clone()) ; + if ( IsNull( pCam)) + return false ; + // assegno i dati + pCam->SetAxes( ( bOk ? CamData::AS_OK : CamData::AS_OUTSTROKE), vAxVal) ; + pCam->SetMoveType( 0) ; + pCam->SetFeed( 0) ; + pCam->SetFlag( nFlag) ; + pCam->SetFlag2( nFlag2) ; + // associo questo oggetto a quello geometrico + m_pGeomDB->SetUserObj( nId, Release( pCam)) ; + + return true ; +} + //---------------------------------------------------------------------------- bool Operation::RemoveClimb( int nClPathId) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; + // recupero gruppo per geometria di lavorazione (Cutter Location) + int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_CL) ; + if ( nClId == GDB_ID_NULL) + return false ; + // se percorso CL specificato, verifico appartenga al gruppo sopra ricavato + if ( nClPathId != GDB_ID_NULL) { + if ( m_pGeomDB->GetParentId( nClPathId) != nClId) + return false ; + } + // altrimenti, recupero il primo percorso CL della operazione + else { + nClPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ; + if ( nClPathId == GDB_ID_NULL) + return false ; + } // elimino tutte le entità CLIMB all'inizio del percorso int nId = m_pGeomDB->GetFirstNameInGroup( nClPathId, MCH_CL_CLIMB) ; while ( nId != GDB_ID_NULL) { @@ -3277,7 +3465,7 @@ Operation::RemoveClimb( int nClPathId) //---------------------------------------------------------------------------- bool -Operation::AddRise( DBLVECTOR& vAxVal, double dDelta, int nClPathId, bool bZHomeDown) +Operation::AddRise( DBLVECTOR& vAxVal, double dDelta, int nClPathId, int nToMinMaxZ) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -3336,17 +3524,22 @@ Operation::AddRise( DBLVECTOR& vAxVal, double dDelta, int nClPathId, bool bZHome // devono esserci almeno i tre assi lineari if ( vAxVal.size() < 3) return false ; - // se delta positivo lo uso come incremento di Z - if ( dDelta > 0 || bZHomeDown) { + // se delta definito lo uso come incremento di Z + if ( isfinite( dDelta)) { vAxVal[2] += dDelta ; nFlag = 0 ; // movimento standard } - // altrimenti uso la Z home + // altrimenti uso HomeZ/MinZ/MaxZ else { - // recupero posizione home - DBLVECTOR vAxHome ; - m_pMchMgr->GetAllCurrAxesHomePos( vAxHome) ; - vAxVal[2] = vAxHome[2] ; + // recupero posizione Z + double dExtrZ ; + if ( nToMinMaxZ == -1) + m_pMchMgr->GetCurrAxisMin( 2, dExtrZ) ; + else if ( nToMinMaxZ == +1) + m_pMchMgr->GetCurrAxisMax( 2, dExtrZ) ; + else + m_pMchMgr->GetCurrAxisHomePos( 2, dExtrZ) ; + vAxVal[2] = dExtrZ ; nFlag = 3 ; // movimento a Zmax nFlag2 = 1 ; } @@ -3434,7 +3627,7 @@ Operation::AddRise( DBLVECTOR& vAxVal, double dDelta, int nClPathId, bool bZHome //---------------------------------------------------------------------------- bool -Operation::AddSpecialRise( const DBLVECTOR& vAxVal, bool bOk, int nClPathId, int nFlag) +Operation::AddSpecialRise( const DBLVECTOR& vAxVal, bool bOk, int nClPathId, int nFlag, int nFlag2) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -3481,7 +3674,7 @@ Operation::AddSpecialRise( const DBLVECTOR& vAxVal, bool bOk, int nClPathId, int pCam->SetMoveType( 0) ; pCam->SetFeed( 0) ; pCam->SetFlag( nFlag) ; - pCam->SetFlag2( 0) ; + pCam->SetFlag2( nFlag2) ; // associo questo oggetto a quello geometrico m_pGeomDB->SetUserObj( nId, Release( pCam)) ; @@ -3623,7 +3816,7 @@ Operation::AddRobotClimb( int nEntId, double dDeltaZ) return false ; DBLVECTOR vAxVal = pCdEnt->GetAxesVal() ; // verifico se richiesta Zmax - bool bZmax = ( dDeltaZ < 0) ; + bool bZmax = ( ! isfinite( dDeltaZ)) ; // calcolo la posizione sopra il punto a Z richiesta DBLVECTOR vAxClimb = vAxVal ; double dNewDeltaZ ; @@ -4514,16 +4707,22 @@ Operation::SpecialMoveZup( DBLVECTOR& vAx, Vector3d& vtTool, int& nFlag, int& nF //---------------------------------------------------------------------------- bool -Operation::SpecialMoveRapid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, DBLVECTOR& vAxNew, bool& bModif) +Operation::SpecialMoveRapid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, int nLinkType, + POSVECTOR& vNewPos, bool& bModif, int& nErase) { // recupero la macchina corrente Machine* pMch = ( m_pMchMgr != nullptr ? m_pMchMgr->GetCurrMachine() : nullptr) ; if ( pMch == nullptr) return false ; // costanti - static const string EMC_VAR = "EMC" ; // tabella variabili locali per calcolo - static const string EVAR_ERROR = ".ERR" ; // OUT (int) codice di errore ( 0 = ok) - static const string EVAR_MODIF = ".MODIF" ; // OUT (bool) flag di modifica effettuata + static const string EMC_VAR = "EMC" ; // tabella variabili locali per calcolo + static const string EVAR_LINKTYPE = ".LINKTYPE" ; // IN (int) codice tipo collegamento (1=FinePrec, 2=InizioSucc, 3=Entrambi)) + static const string EVAR_ERROR = ".ERR" ; // OUT (int) codice di errore ( 0 = ok) + static const string EVAR_MODIF = ".MODIF" ; // OUT (bool) flag di modifica effettuata + static const string EVAR_ERASE = ".ERASE" ; // OUT (int) codice di rimozione movimenti RISE/CLIMB + static const string EVAR_POSTOT = ".POSTOT" ; // OUT (int) numero di nuove posizioni + static const string EVAR_POS = ".POS" ; // OUT (table) vettore di posizioni + static const string EVAR_SIDE = ".SIDE" ; // OUT (int) codice inserimento movimento (-1=prec, 1=curr) static const string ON_SPECIAL_MOVERAPID = "OnSpecialMoveRapid" ; // eseguo l'azione @@ -4536,6 +4735,8 @@ Operation::SpecialMoveRapid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + GVAR_HEAD, GetHeadName()) ; bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + GVAR_EXIT, GetExitNbr()) ; bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + GVAR_TCPOS, GetToolTcPos()) ; + bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + GVAR_MCHID, GetOwner()) ; + bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_LINKTYPE, nLinkType) ; // valore degli assi bool bIsRobot = m_pMchMgr->GetCurrIsRobot() ; int nNumAxes = int( vAxStart.size()) ; @@ -4548,11 +4749,48 @@ Operation::SpecialMoveRapid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, // recupero valori parametri obbligatori bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ; bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_MODIF, bModif) ; - vAxNew.resize( nNumAxes) ; - for ( int i = 1 ; i <= nNumAxes ; ++ i) - bOk = bOk && pMch->LuaGetGlobVar( GetGlobVarAxisValue( i, EMC_VAR, bIsRobot), vAxNew[i-1]) ; + // recupero i parametri facoltativi + if ( ! pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERASE, nErase)) + nErase = 0 ; + int nPosTot ; + if ( ! pMch->LuaGetGlobVar( EMC_VAR + EVAR_POSTOT, nPosTot)) + nPosTot = -1 ; + // recupero gli assi + vNewPos.clear() ; + if ( nPosTot == -1) { + vNewPos.resize( 1) ; + vNewPos[0].vAxis.resize( nNumAxes) ; + for ( int i = 1 ; i <= nNumAxes && bOk ; ++ i) { + if ( ! pMch->LuaGetGlobVar( GetGlobVarAxisValue( i, EMC_VAR, bIsRobot), vNewPos[0].vAxis[i-1])) { + nErr = 91 ; + break ; + } + } + } + else { + for ( int j = 1 ; j <= nPosTot && bOk ; ++ j) { + string sRec = EMC_VAR + EVAR_POS + "." + ToString( j) ; + Position CurrPos ; + if ( ! pMch->LuaGetGlobVar( sRec + EVAR_SIDE, CurrPos.nSide)) { + nErr = 92 ; + break ; + } + CurrPos.vAxis.resize( nNumAxes) ; + for ( int i = 1 ; i <= nNumAxes && bOk ; ++ i) { + if ( ! pMch->LuaGetGlobVar( GetGlobVarAxisValue( i, sRec, bIsRobot), CurrPos.vAxis[i-1])) { + nErr = 93 ; + break ; + } + } + if ( ! pMch->LuaGetGlobVar( sRec + GVAR_FLAG, CurrPos.nFlag)) + CurrPos.nFlag = 0 ; + if ( ! pMch->LuaGetGlobVar( sRec + GVAR_FLAG2, CurrPos.nFlag2)) + CurrPos.nFlag2 = 0 ; + vNewPos.emplace_back( CurrPos) ; + } + } // reset - bOk = bOk && pMch->LuaResetGlobVar( EMC_VAR) ; + bOk = pMch->LuaResetGlobVar( EMC_VAR) && bOk ; // segnalo errori if ( nErr != 0) { bOk = false ; @@ -4563,6 +4801,7 @@ Operation::SpecialMoveRapid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, } else { bModif = false ; + nErase = 0 ; return true ; } } diff --git a/Operation.h b/Operation.h index da97f8a..3a835f5 100644 --- a/Operation.h +++ b/Operation.h @@ -114,6 +114,16 @@ class Operation : public IUserObj protected : Operation( void) ; + protected : + struct Position { + int nSide ; + DBLVECTOR vAxis ; + int nFlag ; + int nFlag2 ; + Position() : nSide( 0), nFlag( 0), nFlag2( 0) {} + } ; + typedef std::vector POSVECTOR ; + protected : bool UpdateFollowingOperationsStatus( int nModif) ; bool GetElevation( int nPhase, const Point3d& ptP, @@ -198,15 +208,17 @@ class Operation : public IUserObj bool bMaxDeltaR2OnFirst, bool bRotContOnNext, double dAngDeltaMinForHome, const DBLVECTOR& vAxRotHome, DBLVECTOR& vAxRotPrec) ; bool AdjustStartEndMovements( bool bVerifyPreviousLink = true) ; - bool AdjustOneStartMovement( int nClPathId, int nPrevClPathId, Operation* pPrevOp, const DBLVECTOR& vAxPrev, bool bMaxZ) ; + bool ManageProtectedAreas( const DBLVECTOR& vAxVal, const DBLVECTOR& vAxIni, Operation* pPrevOp, Operation* pNextOp, bool& bClimbDone) ; + bool AdjustOneStartEndMovement( int nClPathId, int nPrevClPathId, Operation* pPrevOp, const DBLVECTOR& vAxPrev, bool bMaxZ) ; bool ToolChangeNeeded( const Operation& Op1, const Operation& Op2) const ; - bool RemoveClimb( int nClPathId) ; - bool AddRise( DBLVECTOR& vAxVal, double dDelta = - 1, int nClPathId = GDB_ID_NULL, bool bZHomeDown = false) ; - bool AddSpecialRise( const DBLVECTOR& vAxVal, bool bOk = true, int nClPathId = GDB_ID_NULL, int nFlag = 0) ; + bool AddSpecialClimb( const DBLVECTOR& vAxVal, bool bOk = true, int nClPathId = GDB_ID_NULL, int nFlag = 0, int nFlag2 = 0) ; + bool RemoveClimb( int nClPathId = GDB_ID_NULL) ; + bool AddRise( DBLVECTOR& vAxVal, double dDelta = NAN, int nClPathId = GDB_ID_NULL, int nToMinMaxZ = 0) ; + bool AddSpecialRise( const DBLVECTOR& vAxVal, bool bOk = true, int nClPathId = GDB_ID_NULL, int nFlag = 0, int nFlag2 = 0) ; bool RemoveRise( int nClPathId = GDB_ID_NULL) ; bool AddHome( void) ; bool RemoveClimbRiseHome( void) ; - bool AddRobotClimb( int nEntId, double dDeltaZ) ; + bool AddRobotClimb( int nEntId, double dDeltaZ = NAN) ; bool CalcRobotAxesAbovePos( const Point3d& ptP, const Vector3d& vtT, const Vector3d& vtA, double dDeltaZ, DBLVECTOR& vAx, double* pdNewDeltaZ = nullptr) const ; bool CalcDeltaZForHeadRotation( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, double& dDeltaZ) const ; @@ -224,7 +236,8 @@ class Operation : public IUserObj bool TestCollisionAvoid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd) const ; int SpecialTestCollisionAvoid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd) const ; bool SpecialMoveZup( DBLVECTOR& vAx, Vector3d& vtTool, int& nFlag, int& nFlag2, bool& bModif) ; - bool SpecialMoveRapid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, DBLVECTOR& vAxNew, bool& bModif) ; + bool SpecialMoveRapid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, int nLinkType, + POSVECTOR& vNewPos, bool& bModif, int& nErase) ; bool GetAggrBottomData( const std::string& sHead, AggrBottom& agbData) const ; bool IsAggrBottom( const std::string& sHead) const ;