From 493ff4b9e42022b535f9dcd9ba36b3f5dcd5734a Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 4 Apr 2017 07:39:43 +0000 Subject: [PATCH] EgtMachKernel : - si conservano le info delle uscite delle teste al caricamento della macchina - al caricamento di un utensile su una uscita di una testa si caricano anche tutti gli utensili previsti dall'attrezzaggio sulle altre uscite della stessa testa - aggiunta gestione attacchi a elica e zigzag nelle contornature - migliorato controllo collisioni e gestione risalite conseguenti. --- MachConst.h | 4 + MachMgr.h | 3 +- MachMgrMachGroups.cpp | 4 +- MachMgrMachines.cpp | 10 +- Machine.cpp | 6 +- MachineCalc.cpp | 2 + Milling.cpp | 428 +++++++++++++++++++++--------------------- Milling.h | 11 +- Operation.cpp | 130 +++++++++---- Simulator.cpp | 2 +- 10 files changed, 336 insertions(+), 264 deletions(-) diff --git a/MachConst.h b/MachConst.h index 4ecc5cc..88fcc33 100644 --- a/MachConst.h +++ b/MachConst.h @@ -96,6 +96,10 @@ const double FEED_MIN = 1 ; // Massimo angolo al centro per archi di CL const double MAX_ANG_CEN = 150.001 ; +//---------------------------------------------------------------------------- +// Tolleranza su elevazione per attacchi e uscite +const double LIO_ELEV_TOL = 2.0 ; + //---------------------------------------------------------------------------- // Per FlatParts (vedi Nesting di EgtExecutor) const std::string NST_EXT_LAYER = "OutLoop" ; diff --git a/MachMgr.h b/MachMgr.h index 72afa31..a7d2268 100644 --- a/MachMgr.h +++ b/MachMgr.h @@ -358,7 +358,8 @@ class MachMgr : public IMachMgr int GetCurrLinAxes( void) const ; int GetCurrRotAxes( void) const ; bool GetAllCurrAxesName( STRVECTOR& vAxName) const ; - bool GetAllCalcAxesHomePos( DBLVECTOR& vAxHomeVal) const ; + bool GetAllCurrAxesHomePos( DBLVECTOR& vAxHomeVal) const ; + bool GetCurrAxisHomePos( int nInd, double& dHome) const ; bool ApplyRotAxisBlock( void) ; bool IsKinematicRotAxisBlocked( int nInd) const ; double GetCalcRot1W( void) const ; diff --git a/MachMgrMachGroups.cpp b/MachMgrMachGroups.cpp index b7e2fd0..ff04dd1 100644 --- a/MachMgrMachGroups.cpp +++ b/MachMgrMachGroups.cpp @@ -76,11 +76,11 @@ MachMgr::GetMachGroupNewName( string& sName) const } // se nome vuoto, assegno radice standard if ( sName.empty()) - sName = "Mach" ; + sName = "Mach_1" ; // se presenti caratteri vietati, li sostituisco ValidateVal( sName) ; // verifico che il nome sia unico - int nCount = 0 ; + int nCount = 1 ; string sOrigName = sName ; if ( sOrigName.length() > 2 && sOrigName.rfind( "_1") == sOrigName.length() - 2) sOrigName.erase( sOrigName.length() - 2) ; diff --git a/MachMgrMachines.cpp b/MachMgrMachines.cpp index c8f2d19..06a1fac 100644 --- a/MachMgrMachines.cpp +++ b/MachMgrMachines.cpp @@ -468,12 +468,20 @@ MachMgr::GetAllCurrAxesName( STRVECTOR& vAxName) const //---------------------------------------------------------------------------- bool -MachMgr::GetAllCalcAxesHomePos( DBLVECTOR& vAxHomeVal) const +MachMgr::GetAllCurrAxesHomePos( DBLVECTOR& vAxHomeVal) const { Machine* pMch = GetCurrMachine() ; return ( ( pMch != nullptr) ? pMch->GetAllCurrAxesHomePos( vAxHomeVal) : false) ; } +//---------------------------------------------------------------------------- +bool +MachMgr::GetCurrAxisHomePos( int nInd, double& dHome) const +{ + Machine* pMch = GetCurrMachine() ; + return ( ( pMch != nullptr) ? pMch->GetCurrAxisHomePos( nInd, dHome) : false) ; +} + //---------------------------------------------------------------------------- bool MachMgr::GetCalcAngles( const Vector3d& vtDirT, const Vector3d& vtDirA, diff --git a/Machine.cpp b/Machine.cpp index d19033c..3d026c7 100644 --- a/Machine.cpp +++ b/Machine.cpp @@ -446,7 +446,7 @@ Machine::LoadMachineStdHead( const string& sName, const string& sParent, const s double dRot1W, const STROKE& Rot2Stroke, int nSolCh, const string& sGeo, const STRVECTOR& vsAux) { - // recupero pezzo e layer della geometria originale dell'asse + // recupero pezzo e layer della geometria originale della testa string sPart, sLay ; Split( sGeo, "/", true, sPart, sLay) ; // cerco il gruppo nella geometria originale @@ -495,7 +495,7 @@ Machine::LoadMachineMultiHead( const string& sName, const string& sParent, const double dRot1W, const STROKE& Rot2Stroke, int nSolCh, const string& sGeo, const STRVECTOR& vsAux) { - // recupero pezzo e layer della geometria originale dell'asse + // recupero pezzo e layer della geometria originale della testa string sPart, sLay ; Split( sGeo, "/", true, sPart, sLay) ; // cerco il gruppo nella geometria originale @@ -794,6 +794,8 @@ Machine::CreateExitGroups( int nLay, const MUEXITVECTOR& vMuExit) m_pGeomDB->SetStatus( nT, GDB_ST_OFF) ; // assegno nome al gruppo m_pGeomDB->SetName( nGT, sName) ; + // copio le info + m_pGeomDB->CopyAllInfoFrom( nGT, nT) ; // assegno info per eventuale movimento m_pGeomDB->SetInfo( nGT, "Val", 0) ; // installo e inizializzo il gestore dell'uscita diff --git a/MachineCalc.cpp b/MachineCalc.cpp index 1ecdfd7..cae781a 100644 --- a/MachineCalc.cpp +++ b/MachineCalc.cpp @@ -225,6 +225,8 @@ Machine::SetCurrTool( const string& sTool, const string& sHead, int nExit) ! m_pMchMgr->TdbGetCurrToolParam( TPA_TOTLEN, dTOvLen) || ! m_pMchMgr->TdbGetCurrToolParam( TPA_TOTDIAM, dTOvDiam)) return false ; + // carico anche gli utensili su eventuali altre uscite della testa + LoadTools( sHead) ; } // altrimenti casi speciali senza utensile else { diff --git a/Milling.cpp b/Milling.cpp index a458ffa..1ca28ae 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -1124,6 +1124,9 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) LOG_INFO( GetEMkLogger(), "Warning in Milling : skipped Path too small") ; return true ; } + // se una sola entità circonferenza completa, la divido in due per poterla allungare + if ( pCompo->GetCurveCount() == 1 && pCompo->IsClosed()) + pCompo->AddJoint( 0.5) ; // eventuali allungamenti if ( m_Params.m_dStartAddLen > EPS_SMALL) { if ( ! pCompo->ExtendStartByLen( m_Params.m_dStartAddLen)) @@ -1177,7 +1180,6 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) } // eventuale sovrapposizione per percorso chiuso - bool bOverlapOn = false ; if ( pCompo->IsClosed()) { if ( m_Params.m_dOverlap > EPS_SMALL) { double dParS, dParE ; @@ -1186,7 +1188,6 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) PtrOwner pCrv( pCompo->CopyParamRange( dParS, dParE)) ; if ( ! IsNull( pCrv)) { pCompo->AddCurve( Release( pCrv)) ; - bOverlapOn = true ; } } } @@ -1348,6 +1349,7 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) // Se una sola passata if ( dOkStep < EPS_SMALL || dElev <= dOkStep) { + // eseguo lavorazione if ( ! AddStandardMilling( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) return false ; } @@ -1363,13 +1365,6 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) } // se altrimenti passate a spirale else if ( m_Params.m_nStepType == MILL_ST_SPIRAL) { - // elimino eventuale overlap prima aggiunto - if ( bOverlapOn) { - double dLen ; - if ( pCompo->GetLength( dLen)) - pCompo->TrimEndAtLen( dLen - m_Params.m_dOverlap) ; - } - // eseguo if ( ! AddSpiralMilling( pCompo, vtTool, vtExtr, dDepth, dElev, dOkStep, bSplitArcs)) return false ; } @@ -1600,19 +1595,25 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo pCurve->GetStartPoint( ptStart) ; Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; + // determino elevazione su inizio percorso di lavoro + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) + dStElev = dElev ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, false, ptP1)) + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, dStElev, false, ptP1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo bool bOutStart = GetPointOutOfRaw( ptP1, vtTool) ; // aggiungo approccio per frese normali con spazio sopra attacco if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - // determino elevazione su inizio percorso di lavoro - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) - dStElev = dElev ; + // correggo elevazione iniziale con punto inizio attacco dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + if ( IsLeadInHelixZigzagGlide()) { + ptP1 += vtExtr * dStElev ; + dStElev = 0 ; + } // approccio al punto iniziale if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr, bOutStart)) return false ; @@ -1662,18 +1663,20 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo pCurve->GetEndPoint( ptEnd) ; Vector3d vtEnd ; pCurve->GetEndDir( vtEnd) ; + // elevazione sul punto finale + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) + dEndElev = dElev ; // aggiungo uscita Point3d ptP1 ; SetFeed( GetStartFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, false, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, dEndElev, false, bSplitArcs, ptP1)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadOut not computable") ; return false ; } // aggiungo retrazione per frese normali if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) - dEndElev = dElev ; + // correggo elevazione finale con punto fine uscita dEndElev -= ( ptP1 - ptEnd) * vtExtr ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) @@ -1704,10 +1707,10 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool // ciclo sugli step for ( int j = 1 ; j <= nStep ; ++ j) { + // flag direzione (prima passata indice 1) + bool bInvert = ( ( j % 2) == 0) ; // ciclo sulle curve elementari for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // flag direzione (prima passata indice 1) - bool bInvert = ( ( j % 2) == 0) ; // curva corrente const ICurve* pCrvC = pCompo->GetCurve( ( bInvert ? nMaxInd - i : i)) ; // copio la curva @@ -1725,18 +1728,23 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetStartPoint( ptStart) ; Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; - // determino inizio attacco + // determino elevazione su inizio attacco + double dStElev ; + if ( j == 1) { + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) + dStElev = dElev ; + } + else + dStElev = dStep - LIO_ELEV_TOL - 10 * EPS_SMALL ; + // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, bInvert, ptP1)) + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, dStElev, bInvert, ptP1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo bool bOutStart = GetPointOutOfRaw( ptP1, vtTool) ; // se primo step aggiungo approccio per frese normali if ( j == 1 && ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) - dStElev = dElev ; + // correggo elevazione iniziale con punto inizio attacco dStElev -= ( ptP1 - ptStart) * vtExtr ; // approccio al punto iniziale if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr, bOutStart)) @@ -1802,18 +1810,25 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetEndPoint( ptEnd) ; Vector3d vtEnd ; pCurve->GetEndDir( vtEnd) ; + // elevazione sul punto finale + double dEndElev ; + if ( j == nStep) { + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) + dEndElev = dElev ; + } + else + dEndElev = - LIO_ELEV_TOL ; // aggiungo uscita Point3d ptP1 ; SetFeed( GetStartFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, bInvert, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, dEndElev, bInvert, bSplitArcs, ptP1)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadOut not computable") ; return false ; } // se ultimo step aggiungo retrazione per frese normali if ( j == nStep && ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) - dEndElev = dElev ; + // correggo elevazione finale con punto fine uscita + dEndElev -= ( ptP1 - ptEnd) * vtExtr ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) return false ; @@ -1842,6 +1857,9 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool bool bClosed = pCompo->IsClosed() ; int nMaxInd = pCompo->GetCurveCount() - 1 ; + // percorso speciale : chiuso e con attacco a spirale o zigzag + bool bSpecial = bClosed && ( GetLeadInType() == MILL_LI_HELIX || GetLeadInType() == MILL_LI_ZIGZAG) ; + // ciclo sugli step for ( int j = 1 ; j <= nStep ; ++ j) { // ciclo sulle curve elementari @@ -1861,34 +1879,48 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetStartPoint( ptStart) ; Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; - // determino inizio attacco + // punto inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, false, ptP1)) - return false ; - // determino se l'inizio dell'attacco è fuori dal grezzo - bool bOutStart = GetPointOutOfRaw( ptP1, vtTool) ; - // aggiungo approccio per frese normali - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // se speciale e step intermedio + if ( bSpecial && j > 1) { + ptP1 = ptStart + dStep * vtExtr ; + } + // altrimenti + else { // determino elevazione su inizio attacco double dStElev ; if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) dStElev = dElev ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr, bOutStart)) - return false ; - } - // altrimenti, approccio per lame - else { - // verifico di entrare in aria - if ( ! bOutStart) { - m_pMchMgr->SetLastError( 2312, "Error in Milling : LeadIn must be out of rawpart") ; + // determino inizio attacco + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, dStElev, false, ptP1)) return false ; + // determino se l'inizio dell'attacco è fuori dal grezzo + bool bOutStart = GetPointOutOfRaw( ptP1, vtTool) ; + // aggiungo approccio per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // correggo elevazione iniziale con punto inizio attacco + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco + if ( IsLeadInHelixZigzagGlide()) { + ptP1 += vtExtr * ( dStElev - ( j - 1) * dStep) ; + dStElev = ( j - 1) * dStep ; + } + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr, bOutStart)) + return false ; + } + // altrimenti, approccio per lame + else { + // verifico di entrare in aria + if ( ! bOutStart) { + m_pMchMgr->SetLastError( 2312, "Error in Milling : LeadIn must be out of rawpart") ; + return false ; + } + // affondo al punto iniziale + SetFlag( 0) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; } - // affondo al punto iniziale - SetFlag( 0) ; - if ( AddRapidStart( ptP1) == GDB_ID_NULL) - return false ; } // aggiungo attacco SetFeed( GetStartFeed()) ; @@ -1918,23 +1950,29 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } // se ultima entità, uscita e retrazione if ( i == nMaxInd) { + // se speciale e step intermedio salto uscita e retrazione + if ( bSpecial && j != nStep) + continue ; // dati fine entità Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; Vector3d vtEnd ; pCurve->GetEndDir( vtEnd) ; + // elevazione sul punto finale + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) + dEndElev = dElev ; // aggiungo uscita Point3d ptP1 ; SetFeed( GetStartFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, false, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, dEndElev, false, bSplitArcs, ptP1)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadOut not computable") ; return false ; } // aggiungo retrazione per frese normali if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) - dEndElev = dElev ; + // correggo elevazione finale con punto fine uscita + dEndElev -= ( ptP1 - ptEnd) * vtExtr ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) return false ; @@ -1992,18 +2030,19 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool ptStart -= vtStaDepth ; Vector3d vtStart ; pCrvC->GetStartDir( vtStart) ; + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) + dStElev = 0 ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, false, ptP1)) + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, dStElev, false, ptP1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo bool bOutStart = GetPointOutOfRaw( ptP1, vtTool) ; // aggiungo approccio per frese normali if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) - dStElev = 0 ; + // correggo elevazione iniziale con punto inizio attacco dStElev -= ( ptP1 - ptStart) * vtExtr ; // approccio al punto iniziale if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr, bOutStart)) @@ -2058,18 +2097,21 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool ptEnd -= vtEndDepth ; Vector3d vtEnd ; pCrvC->GetEndDir( vtEnd) ; + // elevazione sul punto finale + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) + dEndElev = dElev ; // aggiungo uscita Point3d ptP1 ; SetFeed( GetStartFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, false, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, dEndElev, false, bSplitArcs, ptP1)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadOut not computable") ; return false ; } // aggiungo retrazione per frese normali if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) - dEndElev = dElev ; + // correggo elevazione finale con punto fine uscita + dEndElev -= ( ptP1 - ptEnd) * vtExtr ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) return false ; @@ -2110,16 +2152,17 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool ptStart -= vtStaDepth ; Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) + dStElev = dElev ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, bInvert, ptP1)) + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, dStElev, bInvert, ptP1)) return false ; // aggiungo approccio per frese normali if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) - dStElev = dElev ; + // correggo elevazione iniziale con punto inizio attacco dStElev -= ( ptP1 - ptStart) * vtExtr ; // determino se l'inizio dell'attacco è fuori dal grezzo bool bOutStart = GetPointOutOfRaw( ptP1, vtTool) ; @@ -2170,18 +2213,21 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool ptEnd -= vtEndDepth ; Vector3d vtEnd ; pCurve->GetEndDir( vtEnd) ; + // elevazione sul punto finale + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) + dEndElev = dElev ; // aggiungo uscita Point3d ptP1 ; SetFeed( GetStartFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, bInvert, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, dEndElev, bInvert, bSplitArcs, ptP1)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadOut not computable") ; return false ; } // aggiungo retrazione per frese normali if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) - dEndElev = dElev ; + // correggo elevazione finale con punto fine uscita + dEndElev -= ( ptP1 - ptEnd) * vtExtr ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) return false ; @@ -2320,16 +2366,38 @@ Milling::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, return true ; } +//---------------------------------------------------------------------------- +int +Milling::GetLeadInType( void) const +{ + if ( abs( m_Params.m_dLiTang) < min( 0.1 * m_TParams.m_dDiam, 0.1) && + abs( m_Params.m_dLiPerp) < min( 0.1 * m_TParams.m_dDiam, 0.1)) + return MILL_LI_NONE ; + if ( ( m_Params.m_nLeadInType == MILL_LI_HELIX || m_Params.m_nLeadInType == MILL_LI_ZIGZAG) && + ( m_Params.m_dLiTang < min( 0.1 * m_TParams.m_dDiam, 1.0) || m_Params.m_dLiElev < 10 * EPS_SMALL)) + return MILL_LI_NONE ; + if ( ( m_Params.m_nLeadInType == MILL_LI_HELIX || m_Params.m_nLeadInType == MILL_LI_ZIGZAG || + m_Params.m_nLeadInType == MILL_LI_GLIDE) && m_Params.m_nStepType == MILL_ST_ZIGZAG) + return MILL_LI_NONE ; + if ( ( m_Params.m_nLeadInType == MILL_LI_HELIX || m_Params.m_nLeadInType == MILL_LI_ZIGZAG || + m_Params.m_nLeadInType == MILL_LI_GLIDE) && m_Params.m_nStepType == MILL_ST_SPIRAL) + return MILL_LI_NONE ; + if ( ( m_Params.m_nLeadInType == MILL_LI_HELIX || m_Params.m_nLeadInType == MILL_LI_ZIGZAG) && + ( m_TParams.m_nType & TF_SAWBLADE) != 0) + return MILL_LI_LINEAR ; + return m_Params.m_nLeadInType ; +} + //---------------------------------------------------------------------------- bool -Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, bool bInvert, - Point3d& ptP1) +Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, + double dStElev, bool bInvert, Point3d& ptP1) { // Assegno tipo e parametri - int nType = m_Params.m_nLeadInType ; + int nType = GetLeadInType() ; double dTang = m_Params.m_dLiTang ; double dPerp = m_Params.m_dLiPerp ; - double dElev = m_Params.m_dLiElev ; + double dElev = min( m_Params.m_dLiElev, dStElev + LIO_ELEV_TOL) ; // se step invertito if ( bInvert) { switch ( m_Params.m_nLeadOutType) { @@ -2342,14 +2410,14 @@ Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const if ( m_Params.m_nLeadOutType != MILL_LO_AS_LI) { dTang = m_Params.m_dLoTang ; dPerp = m_Params.m_dLoPerp ; - dElev = m_Params.m_dLoElev ; + dElev = min( m_Params.m_dLoElev, dStElev + LIO_ELEV_TOL) ; } } // senso di rotazione da dir tg a dir esterna bool bCcwRot = (( ! bInvert && m_Params.m_nWorkSide == MILL_WS_LEFT) || ( bInvert && m_Params.m_nWorkSide != MILL_WS_LEFT)) ; - // !!! provvisorio : GLIDE, ZIGZAG e HELIX -> NONE !!! - if ( nType == MILL_LI_GLIDE || nType == MILL_LI_ZIGZAG || nType == MILL_LI_HELIX) + // !!! provvisorio : GLIDE -> NONE !!! + if ( nType == MILL_LI_GLIDE) nType = MILL_LI_NONE ; // Calcolo punto iniziale switch ( nType) { @@ -2367,11 +2435,11 @@ Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const // !!! DA FARE !!! return false ; case MILL_LI_ZIGZAG : - // !!! DA FARE !!! - return false ; + ptP1 = ptStart ; + return true ; case MILL_LI_HELIX : - // !!! DA FARE !!! - return false ; + ptP1 = ptStart ; + return true ; default : return false ; } @@ -2383,10 +2451,10 @@ Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& const Vector3d& vtN, bool bInvert, bool bSplitArcs) { // Assegno il tipo - int nType = m_Params.m_nLeadInType ; + int nType = GetLeadInType() ; // se step invertito if ( bInvert) { - switch ( m_Params.m_nLeadOutType) { + switch ( GetLeadOutType()) { case MILL_LO_LINEAR : nType = MILL_LI_LINEAR ; break ; case MILL_LO_TANGENT : nType = MILL_LI_TANGENT ; break ; case MILL_LO_GLIDE : nType = MILL_LI_GLIDE ; break ; @@ -2394,18 +2462,8 @@ Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& default : nType = MILL_LI_NONE ; break ; } } - // se archi da spezzare - if ( bSplitArcs) { - if ( nType == MILL_LI_TANGENT) - nType = MILL_LI_LINEAR ; - if ( nType == MILL_LI_HELIX) - nType = MILL_LI_ZIGZAG ; - } - // se parametri tg e perp entrambi nulli, allora nessun attacco - if ( (( ptStart - ptP1) ^ vtN).IsSmall()) - nType = MILL_LI_NONE ; - // !!! provvisorio : GLIDE, ZIGZAG e HELIX -> NONE !!! - if ( nType == MILL_LI_GLIDE || nType == MILL_LI_ZIGZAG || nType == MILL_LI_HELIX) + // !!! provvisorio : GLIDE -> NONE !!! + if ( nType == MILL_LI_GLIDE) nType = MILL_LI_NONE ; // Eseguo a seconda del tipo switch ( nType) { @@ -2419,82 +2477,81 @@ Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& if ( IsNull( pCrv)) return false ; pCrv->Invert() ; - if ( pCrv->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCrv) ; - Point3d ptP3 = pLine->GetEnd() ; - return ( AddLinearMove( ptP3, MCH_CL_LEADIN) != GDB_ID_NULL) ; - } - else if ( pCrv->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCrv) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3) ; - // se angolo al centro minore del limite, un solo arco - const double MAX_ANG_CEN = 150 + EPS_ANG_SMALL ; - if ( abs( dAngCen) < MAX_ANG_CEN) { - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - } - // altrimenti due archi - else if ( abs( dAngCen) < 2 * MAX_ANG_CEN){ - Point3d ptMid ; - pArc->GetMidPoint( ptMid) ; - // prima metà arco - if ( AddArcMove( ptMid, ptCen, dAngCen / 2, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - // seconda metà arco - if ( AddArcMove( ptP3, ptCen, dAngCen / 2, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - } - // oppure tre archi - else { - Point3d ptTmp ; - // primo terzo - pArc->GetPointD1D2( 1. / 3, ICurve::FROM_MINUS, ptTmp) ; - if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - // secondo terzo - ptCen.z = ptTmp.z ; - pArc->GetPointD1D2( 2. / 3, ICurve::FROM_MINUS, ptTmp) ; - if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - // ultimo terzo - ptCen.z = ptTmp.z ; - if ( AddArcMove( ptP3, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - } - return true ; - } + return ( AddCurveMove( pCrv, MCH_CL_LEADIN) != GDB_ID_NULL) ; } case MILL_LI_GLIDE : // !!! DA FARE !!! return false ; case MILL_LI_ZIGZAG : - // !!! DA FARE !!! - return false ; + { + double dDeltaN = ( ptStart - ptP1) * vtN ; + int nStep = int( ceil( - dDeltaN / ( m_Params.m_dLiElev + 10 * EPS_SMALL))) ; + double dStep = - dDeltaN / nStep ; + Point3d ptPa = ptP1 + vtStart * 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam) ; + Point3d ptPb = ptP1 - vtStart * 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam) ; + for ( int i = 1 ; i <= nStep ; ++ i) { + if ( AddLinearMove( ptPa - vtN * ( i - 0.75) * dStep, MCH_CL_LEADIN) == GDB_ID_NULL) + return false ; + if ( AddLinearMove( ptPb - vtN * ( i - 0.25) * dStep, MCH_CL_LEADIN) == GDB_ID_NULL) + return false ; + } + return ( AddLinearMove( ptStart, MCH_CL_LEADIN) != GDB_ID_NULL) ; + } case MILL_LI_HELIX : - // !!! DA FARE !!! - return false ; + { + bool bAtLeft = ( m_Params.m_nWorkSide != MILL_WS_RIGHT) ; + // vettore dal punto al centro elica + Vector3d vtCen = vtStart ; + vtCen.Rotate( vtN, ( bAtLeft ? ANG_RIGHT : - ANG_RIGHT)) ; + // dati dell'elica + double dRad = 0.5 * min( m_Params.m_dLiTang, m_TParams.m_dDiam) ; + Point3d ptCen = ptP1 + vtCen * dRad ; + double dDeltaN = ( ptStart - ptP1) * vtN ; + double dAngCen = ceil( - dDeltaN / ( m_Params.m_dLiElev + 10 * EPS_SMALL)) * ( bAtLeft ? ANG_FULL : - ANG_FULL) ; + // creo l'elica + PtrOwner pArc( CreateCurveArc()) ; + if ( IsNull( pArc) || ! pArc->Set( ptCen, vtN, dRad, - vtCen, dAngCen, dDeltaN)) + return false ; + // eventuale spezzatura + if ( bSplitArcs) { + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->AddCurve( Release( pArc)) || ! ApproxWithLines( pCompo)) + return false ; + return ( AddCurveMove( pCompo, MCH_CL_LEADIN) != GDB_ID_NULL) ; + } + else { + // emetto l'elica + return ( AddCurveMove( pArc, MCH_CL_LEADIN) != GDB_ID_NULL) ; + } + } default : return false ; } } +//---------------------------------------------------------------------------- +int +Milling::GetLeadOutType( void) const +{ + if ( abs( m_Params.m_dLoTang) < min( 0.1 * m_TParams.m_dDiam, 0.1) && + abs( m_Params.m_dLoPerp) < min( 0.1 * m_TParams.m_dDiam, 0.1)) + return MILL_LO_NONE ; + return m_Params.m_nLeadOutType ; +} + //---------------------------------------------------------------------------- bool Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - bool bInvert, bool bSplitArcs, Point3d& ptP1) + double dEndElev, bool bInvert, bool bSplitArcs, Point3d& ptP1) { // assegno i parametri - int nType = m_Params.m_nLeadOutType ; + int nType = GetLeadOutType() ; double dTang = m_Params.m_dLoTang ; double dPerp = m_Params.m_dLoPerp ; - double dElev = m_Params.m_dLoElev ; + double dElev = min( m_Params.m_dLoElev, dEndElev + LIO_ELEV_TOL) ; // se uscita come ingresso o step invertito if ( nType == MILL_LO_AS_LI || bInvert) { - switch ( m_Params.m_nLeadInType) { + switch ( GetLeadInType()) { case MILL_LI_LINEAR : nType = MILL_LO_LINEAR ; break ; case MILL_LI_TANGENT : nType = MILL_LO_TANGENT ; break ; case MILL_LI_GLIDE : nType = MILL_LO_GLIDE ; break ; @@ -2504,15 +2561,8 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d } dTang = m_Params.m_dLiTang ; dPerp = m_Params.m_dLiPerp ; - dElev = m_Params.m_dLiElev ; + dElev = min( m_Params.m_dLiElev, dEndElev + LIO_ELEV_TOL) ; } - if ( bSplitArcs) { - if ( nType == MILL_LO_TANGENT) - nType = MILL_LO_LINEAR ; - } - // se parametri nulli, allora nessuna uscita - if ( abs( dTang) < EPS_SMALL && abs( dPerp) < EPS_SMALL ) - nType = MILL_LO_NONE ; // senso di rotazione da dir tg a dir esterna bool bCcwRot = (( ! bInvert && m_Params.m_nWorkSide == MILL_WS_LEFT) || ( bInvert && m_Params.m_nWorkSide != MILL_WS_LEFT)) ; @@ -2526,8 +2576,6 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d return true ; case MILL_LO_LINEAR : { - if ( dTang < 10 * EPS_SMALL && abs( dPerp) < EPS_SMALL) - return false ; Vector3d vtPerp = vtEnd ; vtPerp.Rotate( vtN, ( bCcwRot ? 90 : - 90)) ; ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtN * dElev ; @@ -2536,8 +2584,6 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d case MILL_LO_TANGENT : { // calcolo punto finale dell'uscita - if ( dTang < 10 * EPS_SMALL && abs( dPerp) < EPS_SMALL) - return false ; Vector3d vtPerp = vtEnd ; vtPerp.Rotate( vtN, ( bCcwRot ? 90 : - 90)) ; ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtN * dElev ; @@ -2545,55 +2591,7 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d PtrOwner pCrv( GetArc2PVN( ptEnd, ptP1, vtEnd, vtN)) ; if ( IsNull( pCrv)) return false ; - if ( pCrv->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCrv) ; - Point3d ptP3 = pLine->GetEnd() ; - return ( AddLinearMove( ptP3, MCH_CL_LEADOUT) != GDB_ID_NULL) ; - } - else if ( pCrv->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCrv) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3) ; - // se angolo al centro minore del limite, un solo arco - const double MAX_ANG_CEN = 150 + EPS_ANG_SMALL ; - if ( abs( dAngCen) < MAX_ANG_CEN) { - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - } - // altrimenti due archi - else if ( abs( dAngCen) < 2 * MAX_ANG_CEN){ - Point3d ptMid ; - pArc->GetMidPoint( ptMid) ; - // prima metà arco - if ( AddArcMove( ptMid, ptCen, dAngCen / 2, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - // seconda metà arco - ptCen.z = ptMid.z ; - if ( AddArcMove( ptP3, ptCen, dAngCen / 2, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - } - // oppure tre archi - else { - Point3d ptTmp ; - // primo terzo - pArc->GetPointD1D2( 1. / 3, ICurve::FROM_MINUS, ptTmp) ; - if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - // secondo terzo - ptCen.z = ptTmp.z ; - pArc->GetPointD1D2( 2. / 3, ICurve::FROM_MINUS, ptTmp) ; - if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - // ultimo terzo - ptCen.z = ptTmp.z ; - if ( AddArcMove( ptP3, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - } - return true ; - } + return ( AddCurveMove( pCrv, MCH_CL_LEADOUT) != GDB_ID_NULL) ; } case MILL_LO_GLIDE : // !!! DA FARE !!! diff --git a/Milling.h b/Milling.h index 799a212..bf09976 100644 --- a/Milling.h +++ b/Milling.h @@ -80,12 +80,12 @@ class Milling : public Machining double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr, bool bOutStart) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; - bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, bool bInvert, - Point3d& ptP1) ; + bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, + double dStElev, bool bInvert, Point3d& ptP1) ; bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, bool bInvert, bool bSplitArcs) ; bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - bool bInvert, bool bSplitArcs, Point3d& ptP1) ; + double dEndElev, bool bInvert, bool bSplitArcs, Point3d& ptP1) ; double GetRadiusForStartEndElevation( void) ; bool GetPointOutOfRaw( const Point3d& ptP, const Vector3d& vtTool) ; @@ -104,6 +104,11 @@ class Milling : public Machining { return ( abs( m_Params.m_dOffsL - UNKNOWN_PAR) < EPS_MACH_LEN_PAR ? m_TParams.m_dOffsL : m_Params.m_dOffsL) ; } double GetOffsR() const { return ( abs( m_Params.m_dOffsR - UNKNOWN_PAR) < EPS_MACH_LEN_PAR ? m_TParams.m_dOffsR : m_Params.m_dOffsR) ; } + int GetLeadInType( void) const ; + int GetLeadOutType( void) const ; + bool IsLeadInHelixZigzagGlide() + { int nType = GetLeadInType() ; + return ( nType == MILL_LI_ZIGZAG || nType == MILL_LI_HELIX || nType == MILL_LI_GLIDE) ; } private : SELVECTOR m_vId ; // identificativi entità geometriche da lavorare diff --git a/Operation.cpp b/Operation.cpp index 64e6220..343c97e 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -690,7 +690,7 @@ Operation::CalculateAxesValues( const string& sHint) } // altrimenti uso gli angoli home else { - m_pMchMgr->GetAllCalcAxesHomePos( vAxVal) ; + m_pMchMgr->GetAllCurrAxesHomePos( vAxVal) ; for ( int i = 0 ; i < nRotAxes ; ++ i) vAxRotPrec[i] = vAxVal[nLinAxes + i] ; } @@ -1095,7 +1095,7 @@ Operation::AdjustStartEndMovements( void) if ( ! m_pMchMgr->SetCalcTool( GetToolName(), GetHeadName(), GetExitNbr())) return false ; // recupero posizione home - if ( ! m_pMchMgr->GetAllCalcAxesHomePos( vAxVal)) + if ( ! m_pMchMgr->GetAllCurrAxesHomePos( vAxVal)) return false ; // si parte da Z massima bMaxZ = true ; @@ -1130,13 +1130,31 @@ Operation::AdjustStartEndMovements( void) } // verifico se la testa interferisce con i pezzi o i bloccaggi sulla tavola if ( ! TestCollisionAvoid( vAxVal, vAxIni)) { - // cancello eventuale risalita parziale della lavorazione precedente - pPrevOp->RemoveRise() ; - // aggiungo risalita a Zmax - if ( ! pPrevOp->AddRise( vAxVal)) + // riprovo con risalita parziale + double dHomeZ ; + if ( ! m_pMchMgr->GetCurrAxisHomePos( 2, dHomeZ)) return false ; - // si parte da Z massima - bMaxZ = true ; + double dSafeZ = ( max( vAxVal[2], vAxIni[2]) + dHomeZ) / 2 ; + DBLVECTOR vAxVal2 = vAxVal ; vAxVal2[2] = dSafeZ ; + DBLVECTOR vAxIni2 = vAxIni ; vAxIni2[2] = dSafeZ ; + if ( ! TestCollisionAvoid( vAxVal2, vAxIni2)) { + // cancello eventuale risalita parziale della lavorazione precedente + pPrevOp->RemoveRise() ; + // aggiungo risalita a Zmax + if ( ! pPrevOp->AddRise( vAxVal)) + return false ; + // si parte da Z massima + bMaxZ = true ; + } + else { + // cancello eventuale risalita parziale della lavorazione precedente + pPrevOp->RemoveRise() ; + // aggiungo risalita a Zsafe + if ( ! pPrevOp->AddRise( vAxVal, dSafeZ - vAxVal[2])) + return false ; + // aggiorno quota iniziale in Z + vAxIni[2] = dSafeZ ; + } } } // altrimenti aggiungo uscita per cambio utensile alla lavorazione precedente e parto da questa @@ -1151,7 +1169,7 @@ Operation::AdjustStartEndMovements( void) } else { // recupero posizione home - if ( ! m_pMchMgr->GetAllCalcAxesHomePos( vAxVal)) + if ( ! m_pMchMgr->GetAllCurrAxesHomePos( vAxVal)) return false ; } // imposto l'utensile per i calcoli macchina @@ -1230,17 +1248,21 @@ Operation::AdjustOneStartMovement( int nClPathId, const DBLVECTOR& vAxPrev, bool // verifico se la testa interferisce con i pezzi o i bloccaggi sulla tavola else { // determino la Z più alta tra le due posizioni - double dZtop = max( vAxPrev[2], vAxCurr[2]) ; + double dTopZ = max( vAxPrev[2], vAxCurr[2]) ; // per il test uso posizioni temporanee con questa Z - DBLVECTOR vAxPrevZtop = vAxPrev ; vAxPrevZtop[2] = dZtop ; - DBLVECTOR vAxCurrZtop = vAxCurr ; vAxCurrZtop[2] = dZtop ; + DBLVECTOR vAxPrevTmp = vAxPrev ; vAxPrevTmp[2] = dTopZ ; + DBLVECTOR vAxCurrTmp = vAxCurr ; vAxCurrTmp[2] = dTopZ ; // se interferisce - if ( ! TestCollisionAvoid( vAxPrevZtop, vAxCurrZtop)) { + if ( ! TestCollisionAvoid( vAxPrevTmp, vAxCurrTmp)) { // recupero HomeZ - Machine* pMch = m_pMchMgr->GetCurrMachine() ; double dHomeZ ; - if ( pMch == nullptr || ! pMch->GetCurrAxisHomePos( 2, dHomeZ)) + if ( ! m_pMchMgr->GetCurrAxisHomePos( 2, dHomeZ)) return false ; + // riprovo con una Z intermedia + double dSafeZ = ( dTopZ + dHomeZ) / 2 ; + vAxPrevTmp[2] = dSafeZ ; + vAxCurrTmp[2] = dSafeZ ; + bool bSafeOk = TestCollisionAvoid( vAxPrevTmp, vAxCurrTmp) ; // risalita sopra fine percorso precedente // copio l'entità int nNew1Id = m_pGeomDB->Copy( nEntId, GDB_ID_NULL, nEntId, GDB_BEFORE) ; @@ -1250,7 +1272,7 @@ Operation::AdjustOneStartMovement( int nClPathId, const DBLVECTOR& vAxPrev, bool // modifico questa entità m_pGeomDB->RemoveName( nNew1Id) ; DBLVECTOR vAxNew1 = vAxPrev ; - vAxNew1[2] = dHomeZ ; + vAxNew1[2] = ( bSafeOk ? dSafeZ : dHomeZ) ; int nMask = CamData::MSK_L3 ; // eventuali aggiustamenti speciali dipendenti dalla macchina Vector3d vtTool = pCamData->GetToolDir() ; @@ -1287,7 +1309,7 @@ Operation::AdjustOneStartMovement( int nClPathId, const DBLVECTOR& vAxPrev, bool // modifico quella originale (è la prima del percorso) m_pGeomDB->RemoveName( nNew2Id) ; DBLVECTOR vAxNew2 = vAxCurr ; - vAxNew2[2] = dHomeZ ; + vAxNew2[2] = ( bSafeOk ? dSafeZ : dHomeZ) ; pNew2CamData->SetAxes( CamData::AS_OK, vAxNew2) ; pNew2CamData->ChangeAxesMask( CamData::MSK_L1 | CamData::MSK_L2 | CamData::MSK_R1 | CamData::MSK_R2 | CamData::MSK_R3) ; pNew2CamData->SetFlag( 2) ; @@ -1409,7 +1431,7 @@ Operation::AddRise( DBLVECTOR& vAxVal, double dDelta) else { // recupero posizione home DBLVECTOR vAxHome ; - m_pMchMgr->GetAllCalcAxesHomePos( vAxHome) ; + m_pMchMgr->GetAllCurrAxesHomePos( vAxHome) ; vAxVal[2] = vAxHome[2] ; nFlag = 3 ; // movimento a Zmax } @@ -1510,7 +1532,7 @@ Operation::AddHome( void) int nFlag = 4 ; // recupero coordinate home DBLVECTOR vAxHome ; - m_pMchMgr->GetAllCalcAxesHomePos( vAxHome) ; + m_pMchMgr->GetAllCurrAxesHomePos( vAxHome) ; // assegno i dati pCam->SetAxes( CamData::AS_OK, vAxHome) ; pCam->SetMoveType( 0) ; @@ -1614,7 +1636,6 @@ Operation::TestCollisionAvoid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEn // il numero di assi deve essere costante if ( vAxName.size() != vAxStart.size() || vAxName.size() != vAxEnd.size()) return false ; - // !!! Temporaneo in attesa di gestione attrezzaggio !!! // Se testa con Info ZMAXONROT != 0 e movimento assi rotanti -> collisione int nHeadId = pMch->GetCurrHead() ; int nVal = 0 ; @@ -1650,39 +1671,70 @@ Operation::TestCollisionAvoid( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEn for ( const auto nFxtId : vFxtId) pMch->LinkFixtureToGroup( nFxtId, sTable) ; // Vado nelle posizioni da controllare + const int COLL_STEP = 16 ; bool bCollide = false ; - for ( int i = 1 ; i <= 15 && ! bCollide ; ++ i) { - double dCoeff = double( i) / 16 ; + for ( int i = 1 ; i < COLL_STEP && ! bCollide ; ++ i) { + // Imposto la posizione + double dCoeff = double( i) / COLL_STEP ; for ( size_t j = 0 ; j < vAxStart.size() ; ++ j) { double dPos = ( 1 - dCoeff) * vAxStart[j] + dCoeff * vAxEnd[j] ; pMch->SetAxisPos( vAxName[j], dPos) ; } - // Eseguo controllo + // Determino sottobox e box della testa + BOXIVECTOR vbiSH ; BBox3d b3Head ; - m_pGeomDB->GetGlobalBBox( pMch->GetCurrHead(), b3Head, BBF_ONLY_VISIBLE) ; + int nHId = m_pGeomDB->GetFirstGroupInGroup( pMch->GetCurrHead()) ; + while ( nHId != GDB_ID_NULL) { + BBox3d b3Tmp ; + m_pGeomDB->GetGlobalBBox( nHId, b3Tmp, BBF_ONLY_VISIBLE) ; + b3Head.Add( b3Tmp) ; + vbiSH.emplace_back( b3Tmp, nHId) ; + nHId = m_pGeomDB->GetNextGroup( nHId) ; + } + // Li confronto con i grezzi for ( const auto nRawId : vRawId) { + // verifico i box BBox3d b3Raw ; int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; if ( m_pGeomDB->GetGlobalBBox( nRawSolidId, b3Raw) && b3Head.Overlaps( b3Raw)) { - // box testa nel riferimento del solido + // riferimento del grezzo Frame3d frSolid ; m_pGeomDB->GetGlobFrame( nRawSolidId, frSolid) ; - BBox3d b3Hsol ; - m_pGeomDB->GetRefBBox( pMch->GetCurrHead(), frSolid, b3Hsol) ; - // solido - const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawSolidId)) ; - // verifica di collisione tra box e solido - if ( pStm == nullptr || CDBoxPolyhedron( b3Hsol, *pStm)) - bCollide = true ; - break ; + // verifico i sottobox + for ( const auto biSH : vbiSH) { + if ( biSH.first.Overlaps( b3Raw)) { + // sottobox testa nel riferimento del solido + BBox3d b3Hsol ; + m_pGeomDB->GetRefBBox( biSH.second, frSolid, b3Hsol) ; + // solido + const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawSolidId)) ; + // verifica di collisione tra sottobox e solido + if ( pStm == nullptr || CDBoxPolyhedron( b3Hsol, *pStm)) { + bCollide = true ; + break ; + } + } + } + if ( bCollide) + break ; } } - for ( const auto nFxtId : vFxtId) { - BBox3d b3Fxt ; - int nFlag = BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_TEXT ; - if ( m_pGeomDB->GetGlobalBBox( nFxtId, b3Fxt, nFlag) && b3Head.Overlaps( b3Fxt)) { - bCollide = true ; - break ; + if ( ! bCollide) { + for ( const auto nFxtId : vFxtId) { + // verifico i box + BBox3d b3Fxt ; + int nFlag = BBF_ONLY_VISIBLE | BBF_IGNORE_TEXT | BBF_IGNORE_DIM ; + if ( m_pGeomDB->GetGlobalBBox( nFxtId, b3Fxt, nFlag) && b3Head.Overlaps( b3Fxt)) { + // verifico i sottobox + for ( const auto biSH : vbiSH) { + if ( biSH.first.Overlaps( b3Fxt)) { + bCollide = true ; + break ; + } + } + if ( bCollide) + break ; + } } } } diff --git a/Simulator.cpp b/Simulator.cpp index 5fd8997..b69ab5e 100644 --- a/Simulator.cpp +++ b/Simulator.cpp @@ -260,7 +260,7 @@ Simulator::GoHome( void) // reset stato macchina OnResetMachine() ; // assegno valori home degli assi macchina attivi - return m_pMchMgr->GetAllCalcAxesHomePos( m_AxesVal) ; + return m_pMchMgr->GetAllCurrAxesHomePos( m_AxesVal) ; } //----------------------------------------------------------------------------