From 7d819a950041d3f5e89ac921c3bb246365fff0ca Mon Sep 17 00:00:00 2001 From: DarioS Date: Mon, 13 Mar 2023 08:14:28 +0100 Subject: [PATCH] EgtMachKernel : - modifiche a fresature per approcci e retrazioni di lame e frese che non lavorano di testa - in simulatore migliorati controlli per frese che non lavorano di testa. --- Milling.cpp | 463 +++++++++++++++++++++++++++++++++++++------------- Milling.h | 11 +- Pocketing.cpp | 8 +- Pocketing.h | 2 +- Simulator.cpp | 50 ++++-- Simulator.h | 1 + 6 files changed, 402 insertions(+), 133 deletions(-) diff --git a/Milling.cpp b/Milling.cpp index c239998..3c30822 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -124,6 +124,8 @@ Milling::Clone( void) const pMill->m_bAggrBottom = m_bAggrBottom ; pMill->m_dCurrOscillLen = m_dCurrOscillLen ; pMill->m_dCurrTabsLen = m_dCurrTabsLen ; + pMill->m_bStartOutRaw = m_bStartOutRaw ; + pMill->m_bEndOutRaw = m_bEndOutRaw ; } catch( ...) { delete pMill ; @@ -248,6 +250,8 @@ Milling::Milling( void) m_bAggrBottom = false ; m_dCurrOscillLen = 0 ; m_dCurrTabsLen = 0 ; + m_bStartOutRaw = false ; + m_bEndOutRaw = false ; } //---------------------------------------------------------------------------- @@ -1878,6 +1882,12 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) if ( ! VerifyPathFromBottom( pCompo, vtTool)) return false ; + // recupero eventuale flag di inizio forzato fuori dal grezzo + int nStartOutRaw ; + FromString( ExtractInfo( m_Params.m_sUserNotes, "OutRaw="), nStartOutRaw) ; + m_bStartOutRaw = (( nStartOutRaw & 1) != 0) ; + m_bEndOutRaw = (( nStartOutRaw & 2) != 0) ; + // se richiesta anteprima if ( nPvId != GDB_ID_NULL) { // creo gruppo per geometria di anteprima del percorso @@ -2283,7 +2293,7 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; if ( ! vtAppr.Normalize()) vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; - bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dElev, dSafeZ) ; + bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dStElev, dSafeZ) ; // determino se l'inizio dell'attacco è sopra il grezzo bool bGeomAboveStart = GetPointAboveRaw( ptP1, vtTool) ; bool bAboveStart = false ; @@ -2295,8 +2305,9 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo } // imposto versore correzione e ausiliario sul punto di partenza CalcAndSetCorrAuxDir( pCompo, i) ; - // aggiungo approccio per frese normali - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // aggiungo approccio per frese normali e frese che non lavorano di testa con attacco opportuno oppure fuori + if ( ( m_TParams.m_nType & TF_MILL) != 0 && + ( m_TParams.m_nType != TT_MILL_NOTIP || LeadInRawIsOk() || m_bStartOutRaw || bOutStart)) { // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) Vector3d vtEscape = vtTool ; if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || @@ -2326,7 +2337,7 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo return false ; } } - // altrimenti, approccio per lame + // altrimenti, approccio per lame e frese che non lavorano di testa else { // verifico di entrare in aria if ( ! bOutStart) { @@ -2449,8 +2460,14 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } - // aggiungo retrazione per frese normali - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // determino se la fine dell'uscita è fuori dal grezzo + Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; + if ( ! vtRetr.Normalize()) + vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + bool bOutEnd = GetPointOutOfRaw( ptP1, vtTool, vtRetr, dEndElev, dSafeZ) ; + // aggiungo retrazione per frese normali e frese che non lavorano di testa già fuori + if ( ( m_TParams.m_nType & TF_MILL) != 0 && + ( m_TParams.m_nType != TT_MILL_NOTIP || m_bEndOutRaw || bOutEnd)) { // determino se la fine dell'uscita è sopra il grezzo bool bAboveEnd = false ; if ( m_bAboveHead) { @@ -2485,13 +2502,8 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo return false ; } } - // per lame quando è necessario + // per lame e frese che non lavorano di testa quando è necessario else { - // verifico di uscire in aria - Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; - if ( ! vtRetr.Normalize()) - vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; - bool bOutEnd = GetPointOutOfRaw( ptP1, vtTool, vtRetr, dElev, dSafeZ) ; if ( ! bOutEnd) { // verifico se sono sopra bool bGeomAboveEnd = GetPointAboveRaw( ptP1, vtTool) ; @@ -2585,6 +2597,7 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool int nMaxInd = pCompo->GetCurveCount() - 1 ; // ciclo sugli step + bool bOk = true ; for ( int k = 1 ; k <= nStep ; ++ k) { // flag direzione (prima passata indice 1) bool bInvert = ( ( k % 2) == 0) ; @@ -2612,79 +2625,138 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetStartDir( vtStart) ; // determino elevazione su inizio attacco double dStElev ; - if ( k == 1) { - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dStep ; - } - else - dStElev = dStep - LIO_ELEV_TOL - 10 * EPS_SMALL ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dStep ; // determino inizio attacco Point3d ptP1 ; if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, bInvert, pCompo, ptP1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo - Vector3d vtCorr = CalcCorrDir( pCompo, ( bInvert ? nMaxInd + 1 : 0)) ; - bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtCorr, dElev, dSafeZ) ; + Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; + if ( ! vtAppr.Normalize()) + vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dStElev, dSafeZ) ; // determino se l'inizio dell'attacco è sopra il grezzo + bool bGeomAboveStart = GetPointAboveRaw( ptP1, vtTool) ; bool bAboveStart = false ; if ( m_bAboveHead) { if ( ! m_bTiltingTab) - bAboveStart = GetPointAboveRaw( ptP1, vtTool) ; + bAboveStart = bGeomAboveStart ; else bAboveStart = bOutStart ; } // imposto versore correzione e ausiliario sul punto di partenza CalcAndSetCorrAuxDir( pCompo, ( bInvert ? nMaxInd - i + 1 : i)) ; - // se primo step aggiungo approccio per frese normali - if ( k == 1 && ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) - Vector3d vtEscape = vtTool ; - if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || - ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { - vtEscape.z = 0 ; - vtEscape.Normalize() ; + // se primo step + if ( k == 1) { + // aggiungo approccio per frese normali e frese che non lavorano di testa con attacco opportuno oppure fuori + if ( ( m_TParams.m_nType & TF_MILL) != 0 && + ( m_TParams.m_nType != TT_MILL_NOTIP || LeadInRawIsOk() || m_bStartOutRaw || bOutStart)) { + // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) + Vector3d vtEscape = vtTool ; + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { + vtEscape.z = 0 ; + vtEscape.Normalize() ; + } + double dNewStElev ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { + if ( bAboveStart || dNewStElev > EPS_SMALL) + dStElev = min( dStElev, dNewStElev) ; + } + // se testa sopra determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione + bool bAhUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; + // se testa sotto determino se l'inizio dell'attacco è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; + // se attacco a zigzag o a spirale, l'elevazione va nell'attacco + if ( IsLeadInHelixOrZigzag()) { + ptP1 += vtTool * ( dStElev + LIO_ELEV_TOL) ; + dStElev = - LIO_ELEV_TOL ; + } + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart, bAboveStart)) { + m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; + return false ; + } } - double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { - if ( bAboveStart || dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - } - // se testa sopra determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bAhUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; - // se testa sotto determino se l'inizio dell'attacco è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione - bool bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; - // se attacco a zigzag o a spirale, l'elevazione va nell'attacco - if ( IsLeadInHelixOrZigzag()) { - ptP1 += vtTool * ( dStElev + LIO_ELEV_TOL) ; - dStElev = - LIO_ELEV_TOL ; - } - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart, bAboveStart)) { - m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; - return false ; + // altrimenti, approccio per lame e frese che non lavorano di testa + else { + // verifico di entrare in aria + if ( ! bOutStart) { + // verifico se sono sotto + double dSawStartElev = 0 ; + bool bUnderStart = false ; + bool bSideStart = false ; + if ( ! bGeomAboveStart) { + bUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, + GetRadiusForStartEndElevation( false), + m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; + + } + // se non sono sotto, verifico se posso allontanarmi nel piano lama (meglio se in orizzontale) + if ( ! bUnderStart) { + Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; + Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + Vector3d vtAppr2 = ptP1 - ptStart ; + if ( ! vtAppr2.Normalize()) + vtAppr2 = CalcCorrDir( pCompo, i) ; + double dSawStartElev1 = -1, dSawStartElev2 = -1 ; + GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtAppr1, dSawStartElev1) ; + GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtAppr2, dSawStartElev2) ; + if ( dSawStartElev1 > -EPS_SMALL && dSawStartElev2 > -EPS_SMALL) { + bool bFirst = ( dSawStartElev1 < dSawStartElev2) ; + vtAppr = ( bFirst ? vtAppr1 : vtAppr2) ; + dSawStartElev = ( bFirst ? dSawStartElev1 : dSawStartElev2) ; + bSideStart = true ; + } + else if ( dSawStartElev1 > -EPS_SMALL) { + vtAppr = vtAppr1 ; + dSawStartElev = dSawStartElev1 ; + bSideStart = true ; + } + else if ( dSawStartElev2 > -EPS_SMALL) { + vtAppr = vtAppr2 ; + dSawStartElev = dSawStartElev2 ; + bSideStart = true ; + } + } + if ( ! bGeomAboveStart && ! bUnderStart && ! bSideStart && bOk) { + m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; + bOk = false ; + } + // aggiungo opportuno approccio + if ( ! AddSawBladeSideApproach( ptP1, vtAppr, dSafeZ, dSawStartElev, dAppr)) { + m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; + return false ; + } + } + else { + // affondo al punto iniziale + SetFlag( 0) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + } } } // altrimenti, affondo al punto iniziale else { - // se lama - if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0) { - SetFlag( 0) ; - if ( k == 1) { - // verifico di entrare in aria - if ( ! bOutStart) { - m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; - return false ; - } - // eseguo affondo - if ( AddRapidStart( ptP1) == GDB_ID_NULL) - return false ; - } - else { - if ( AddRapidMove( ptP1) == GDB_ID_NULL) + // se lama o fresa che non lavora di testa + if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0 || m_TParams.m_nType == TT_MILL_NOTIP) { + SetFeed( GetStartFeed()) ; + // eventuale movimento parallelo all'asse utensile fatto fuori + Point3d ptCurr ; + if ( ! GetCurrPos( ptCurr)) + return false ; + Vector3d vtToolOrt = OrthoCompo( ptP1 - ptCurr, vtTool) ; + if ( vtToolOrt.Len() > 100 * EPS_SMALL) { + if ( AddLinearMove( ptP1 - vtToolOrt) == GDB_ID_NULL) return false ; } + // movimento standard + if ( AddLinearMove( ptP1) == GDB_ID_NULL) + return false ; } // se attacco a zigzag o a spirale, non affondo else if ( IsLeadInHelixOrZigzag()) { @@ -2693,7 +2765,7 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } // altrimenti, affondo in feed opportuna else { - bool bStartFeed = ( bOutStart || m_TParams.m_nType == TT_MILL_NOTIP || m_TParams.m_nType == TT_MILL_POLISHING) ; + bool bStartFeed = ( bOutStart || m_TParams.m_nType == TT_MILL_POLISHING) ; SetFeed( bStartFeed ? GetStartFeed() : GetTipFeed()) ; if ( AddLinearMove( ptP1) == GDB_ID_NULL) return false ; @@ -2755,12 +2827,8 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetEndDir( vtEnd) ; // elevazione sul punto finale double dEndElev ; - if ( k == nStep) { - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) - dEndElev = dElev ; - } - else - dEndElev = - LIO_ELEV_TOL ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + dEndElev = dElev ; // se non c'è attacco a zigzag o a spirale oppure ultimo step, aggiungo uscita Point3d ptP1 = ptEnd ; if ( ! IsLeadInHelixOrZigzag() || k == nStep) { @@ -2770,8 +2838,65 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool return false ; } } - // se ultimo step aggiungo retrazione per frese normali - if ( k == nStep && ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // determino se la fine dell'uscita è fuori dal grezzo + Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; + if ( ! vtRetr.Normalize()) + vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + bool bOutEnd = GetPointOutOfRaw( ptP1, vtTool, vtRetr, dEndElev, dSafeZ) ; + // per lame e frese che non lavorano di testa quando ancora dentro aggiungo retrazione se necessaria + if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0 || + ( m_TParams.m_nType == TT_MILL_NOTIP && ! m_bEndOutRaw && ! bOutEnd)) { + if ( ! bOutEnd) { + // verifico se sono sopra + bool bGeomAboveEnd = GetPointAboveRaw( ptP1, vtTool) ; + // verifico se sono sotto + double dSawEndElev = 0 ; + bool bUnderEnd = false ; + bool bSideEnd = false ; + if ( ! bGeomAboveEnd) { + bUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, + GetRadiusForStartEndElevation( false), + m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; + } + if ( ! bUnderEnd) { + Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; + Vector3d vtRetr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + Vector3d vtRetr2 = ptP1 - ptEnd ; + if ( ! vtRetr2.Normalize()) + vtRetr2 = CalcCorrDir( pCompo, i + 1) ; + double dSawEndElev1, dSawEndElev2 ; + GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtRetr1, dSawEndElev1) ; + GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtRetr2, dSawEndElev2) ; + if ( dSawEndElev1 > -EPS_SMALL && dSawEndElev2 > -EPS_SMALL) { + bool bFirst = ( dSawEndElev1 < dSawEndElev2) ; + vtRetr = ( bFirst ? vtRetr1 : vtRetr2) ; + dSawEndElev = ( bFirst ? dSawEndElev1 : dSawEndElev2) ; + bSideEnd = true ; + } + else if ( dSawEndElev1 > -EPS_SMALL) { + vtRetr = vtRetr1 ; + dSawEndElev = dSawEndElev1 ; + bSideEnd = true ; + } + else if ( dSawEndElev2 > -EPS_SMALL) { + vtRetr = vtRetr2 ; + dSawEndElev = dSawEndElev2 ; + bSideEnd = true ; + } + } + if ( ! bGeomAboveEnd && ! bUnderEnd && ! bSideEnd && bOk) { + m_pMchMgr->SetLastError( 2324, "Error in Milling : LeadOut must be out of rawpart") ; + bOk = false ; + } + // aggiungo opportuna retrazione + if ( ! AddSawBladeSideRetract( ptP1, vtRetr, dSafeZ, dSawEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; + return false ; + } + } + } + // altrimenti frese e se ultimo step aggiungo retrazione + else if ( k == nStep) { // determino se la fine dell'uscita è sopra il grezzo bool bAboveEnd = false ; if ( m_bAboveHead) { @@ -2806,11 +2931,10 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool return false ; } } - // per lame non è necessario } } } - return true ; + return bOk ; } //---------------------------------------------------------------------------- @@ -2922,6 +3046,7 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool double dStep = dElev / nStep ; // ciclo sugli step + bool bOk = true ; int nMaxInd = pCompo->GetCurveCount() - 1 ; for ( int k = 1 ; k <= nStep ; ++ k) { int j = ( bStepUp ? nStep - k + 1 : k) ; @@ -2964,10 +3089,13 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, false, pCompo, ptP1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo - Vector3d vtCorr = CalcCorrDir( pCompo, i) ; - bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtCorr, dElev, dSafeZ) ; - // aggiungo approccio per frese normali - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; + if ( ! vtAppr.Normalize()) + vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dStElev, dSafeZ) ; + // aggiungo approccio per frese normali e frese che non lavorano di testa con attacco opportuno oppure fuori + if ( ( m_TParams.m_nType & TF_MILL) != 0 && + ( m_TParams.m_nType != TT_MILL_NOTIP || LeadInRawIsOk() || m_bStartOutRaw || bOutStart)) { // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) Point3d ptP1m = ptP1 - 10 * EPS_SMALL * vtTool ; Vector3d vtEscape = vtTool ; @@ -3009,17 +3137,65 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } } } - // altrimenti, approccio per lame + // altrimenti, approccio per lame e frese che non lavorano di testa else { // verifico di entrare in aria if ( ! bOutStart) { - m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; - return false ; + // verifico se sono sopra + bool bGeomAboveStart = GetPointAboveRaw( ptP1, vtTool) ; + // verifico se sono sotto + double dSawStartElev = 0 ; + bool bUnderStart = false ; + bool bSideStart = false ; + if ( ! bGeomAboveStart) { + bUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, + GetRadiusForStartEndElevation( false), + m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; + + } + // se non sono sotto, verifico se posso allontanarmi nel piano lama (meglio se in orizzontale) + if ( ! bUnderStart) { + Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; + Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + Vector3d vtAppr2 = ptP1 - ptStart ; + if ( ! vtAppr2.Normalize()) + vtAppr2 = CalcCorrDir( pCompo, i) ; + double dSawStartElev1 = -1, dSawStartElev2 = -1 ; + GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtAppr1, dSawStartElev1) ; + GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtAppr2, dSawStartElev2) ; + if ( dSawStartElev1 > -EPS_SMALL && dSawStartElev2 > -EPS_SMALL) { + bool bFirst = ( dSawStartElev1 < dSawStartElev2) ; + vtAppr = ( bFirst ? vtAppr1 : vtAppr2) ; + dSawStartElev = ( bFirst ? dSawStartElev1 : dSawStartElev2) ; + bSideStart = true ; + } + else if ( dSawStartElev1 > -EPS_SMALL) { + vtAppr = vtAppr1 ; + dSawStartElev = dSawStartElev1 ; + bSideStart = true ; + } + else if ( dSawStartElev2 > -EPS_SMALL) { + vtAppr = vtAppr2 ; + dSawStartElev = dSawStartElev2 ; + bSideStart = true ; + } + } + if ( ! bGeomAboveStart && ! bUnderStart && ! bSideStart && bOk) { + m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; + bOk = false ; + } + // aggiungo opportuno approccio + if ( ! AddSawBladeSideApproach( ptP1, vtAppr, dSafeZ, dSawStartElev, dAppr)) { + m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; + return false ; + } + } + else { + // 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 @@ -3092,40 +3268,99 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } - // aggiungo retrazione per frese normali (esclusi step intermedi senza retrazione) - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0 && ( j == nStep || bMidRetract)) { - // correggo elevazione finale per punto fine uscita (se testa da sopra senza aggregato approccio mai Z-) - Point3d ptP1m = ptP1 - 10 * EPS_SMALL * vtTool ; - Vector3d vtEscape = vtTool ; - if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || - ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { - vtEscape.z = 0 ; - vtEscape.Normalize() ; + // se step finale o intermedi con retrazione + if ( j == nStep || bMidRetract) { + // determino se la fine dell'uscita è fuori dal grezzo + Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; + if ( ! vtRetr.Normalize()) + vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + bool bOutEnd = GetPointOutOfRaw( ptP1, vtTool, vtRetr, dEndElev, dSafeZ) ; + // aggiungo retrazione per frese normali e frese che non lavorano di testa già fuori + if ( ( m_TParams.m_nType & TF_MILL) != 0 && + ( m_TParams.m_nType != TT_MILL_NOTIP || m_bEndOutRaw || bOutEnd)) { + // correggo elevazione finale per punto fine uscita (se testa da sopra senza aggregato approccio mai Z-) + Point3d ptP1m = ptP1 - 10 * EPS_SMALL * vtTool ; + Vector3d vtEscape = vtTool ; + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { + vtEscape.z = 0 ; + vtEscape.Normalize() ; + } + double dNewEndElev ; + if ( GetElevation( m_nPhase, ptP1m, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { + if ( bAboveStartEnd ) + dEndElev = min( dEndElev, dNewEndElev) ; + else if ( dNewEndElev > EPS_SMALL) + dEndElev = max( dEndElev, dNewEndElev) ; + } + // se testa sopra, determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione + bool bAhUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; + // se testa sotto, determino se l'inizio dell'uscita è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveStartEnd)) { + m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; + return false ; + } } - double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1m, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { - if ( bAboveStartEnd ) - dEndElev = min( dEndElev, dNewEndElev) ; - else if ( dNewEndElev > EPS_SMALL) - dEndElev = max( dEndElev, dNewEndElev) ; - } - // se testa sopra, determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bAhUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; - // se testa sotto, determino se l'inizio dell'uscita è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione - bool bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), - m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; - // aggiungo retrazione - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveStartEnd)) { - m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; - return false ; + // per lame e frese che non lavorano di testa quando è necessario + else { + if ( ! bOutEnd) { + // verifico se sono sopra + bool bGeomAboveEnd = GetPointAboveRaw( ptP1, vtTool) ; + // verifico se sono sotto + double dSawEndElev = 0 ; + bool bUnderEnd = false ; + bool bSideEnd = false ; + if ( ! bGeomAboveEnd) { + bUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, + GetRadiusForStartEndElevation( false), + m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; + } + if ( ! bUnderEnd) { + Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; + Vector3d vtRetr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + Vector3d vtRetr2 = ptP1 - ptEnd ; + if ( ! vtRetr2.Normalize()) + vtRetr2 = CalcCorrDir( pCompo, i + 1) ; + double dSawEndElev1, dSawEndElev2 ; + GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtRetr1, dSawEndElev1) ; + GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtRetr2, dSawEndElev2) ; + if ( dSawEndElev1 > -EPS_SMALL && dSawEndElev2 > -EPS_SMALL) { + bool bFirst = ( dSawEndElev1 < dSawEndElev2) ; + vtRetr = ( bFirst ? vtRetr1 : vtRetr2) ; + dSawEndElev = ( bFirst ? dSawEndElev1 : dSawEndElev2) ; + bSideEnd = true ; + } + else if ( dSawEndElev1 > -EPS_SMALL) { + vtRetr = vtRetr1 ; + dSawEndElev = dSawEndElev1 ; + bSideEnd = true ; + } + else if ( dSawEndElev2 > -EPS_SMALL) { + vtRetr = vtRetr2 ; + dSawEndElev = dSawEndElev2 ; + bSideEnd = true ; + } + } + if ( ! bGeomAboveEnd && ! bUnderEnd && ! bSideEnd && bOk) { + m_pMchMgr->SetLastError( 2324, "Error in Milling : LeadOut must be out of rawpart") ; + bOk = false ; + } + // aggiungo opportuna retrazione + if ( ! AddSawBladeSideRetract( ptP1, vtRetr, dSafeZ, dSawEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; + return false ; + } + } } } - // per lame non è necessario } } } - return true ; + return bOk ; } //---------------------------------------------------------------------------- diff --git a/Milling.h b/Milling.h index 9b2f6ee..6494654 100644 --- a/Milling.h +++ b/Milling.h @@ -145,7 +145,14 @@ class Milling : public Machining bool IsLeadInHelixOrZigzag() const { int nType = GetLeadInType() ; return ( nType == MILL_LI_ZIGZAG || nType == MILL_LI_HELIX) ; } - friend class LeadIOStatus ; + bool LeadInRawIsOk( void) const + { if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0) + return false ; + if ( m_TParams.m_nType != TT_MILL_NOTIP) + return true ; + return ( IsLeadInHelixOrZigzag() && + m_Params.m_dLiTang >= 0.9 * m_TParams.m_dDiam && m_Params.m_dLiElev <= 2) ; } + friend class LeadIOStatus ; private : SELVECTOR m_vId ; // identificativi entità geometriche da lavorare @@ -167,4 +174,6 @@ class Milling : public Machining AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto double m_dCurrOscillLen ; // lunghezza corrente lungo il percorso per l'oscillazione double m_dCurrTabsLen ; // lunghezza corrente lungo il percorso per tabs + bool m_bStartOutRaw ; // flag forzatura inizio fuori dal grezzo + bool m_bEndOutRaw ; // flag forzatura fine fuori dal grezzo } ; \ No newline at end of file diff --git a/Pocketing.cpp b/Pocketing.cpp index 617d27c..185f20b 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -1991,7 +1991,7 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con // se non ottimizzato e utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore if ( ( ! bOptimizedZigZag || ! ( bOutRawLeadIn || m_bOpenOutRaw)) && m_TParams.m_nType == TT_MILL_NOTIP) { - if ( ! LeadInIsOk()) { + if ( ! LeadInRawIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } @@ -3007,7 +3007,7 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con // se utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP) { - if ( ! LeadInIsOk()) { + if ( ! LeadInRawIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } @@ -3384,7 +3384,7 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart && ! bForcedOutStart) { - if ( ! LeadInIsOk()) { + if ( ! LeadInRawIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } @@ -3604,7 +3604,7 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) { - if ( ! LeadInIsOk()) { + if ( ! LeadInRawIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } diff --git a/Pocketing.h b/Pocketing.h index bdfa5d5..d85b00d 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -165,7 +165,7 @@ class Pocketing : public Machining if ( m_Params.m_nLeadInType != POCKET_LI_GLIDE && m_Params.m_dLiElev < 10 * EPS_SMALL) return POCKET_LI_NONE ; return m_Params.m_nLeadInType ; } - int LeadInIsOk( void) const + bool LeadInRawIsOk( void) const { if ( m_TParams.m_nType != TT_MILL_NOTIP) return true ; return (( GetLeadInType() == POCKET_LI_ZIGZAG || GetLeadInType() == POCKET_LI_HELIX) && diff --git a/Simulator.cpp b/Simulator.cpp index 31211e0..c71e09b 100644 --- a/Simulator.cpp +++ b/Simulator.cpp @@ -72,6 +72,7 @@ Simulator::Simulator( void) m_nAuxEInd = 0 ; m_nExit = 0 ; m_dTDiam = 0 ; + m_bCutOnTip = false ; m_dSafeDist = SAFEDIST_STD ; m_nAxesMask = 0 ; m_bEnabAxes = true ; @@ -134,6 +135,7 @@ Simulator::Start( bool bFirst) m_sHead.clear() ; m_nExit = 0 ; m_dTDiam = 0 ; + m_bCutOnTip = false ; ResetInterpolation() ; ResetAxes() ; ResetAuxAxes() ; @@ -470,6 +472,9 @@ Simulator::UpdateTool( bool bFirst, int& nErr) m_sHead = sHead ; m_nExit = nExit ; m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ; + double dTipFeed = 0 ; + m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ; + m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ; // ripristino la lavorazione corrente m_pMchMgr->SetCurrMachining( nCurrMchId) ; // aggiorno gli assi macchina @@ -509,6 +514,9 @@ Simulator::UpdateTool( bool bFirst, int& nErr) m_sHead = sHead ; m_nExit = nExit ; m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ; + double dTipFeed = 0 ; + m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ; + m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ; // aggiorno gli assi macchina if ( ! UpdateAxes()) return false ; @@ -1038,21 +1046,28 @@ Simulator::ManageSingleMove( int& nStatus, double& dMove) } m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ; } - // eseguo eventuale collision check - bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ; - } - // se non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill - if ( nMoveType != 0 || ! NeedCollisionCheck()) { - for ( int i = 0 ; i < int( m_VmTool.size()) ; ++ i) { - Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ; - bool bOkF = GetHeadCurrPosDirAux( m_VmTool[i].sHead, m_VmTool[i].nExit, ptNoseF, vtDirF, vtAuxF) ; - for ( int j = 0 ; j < int( m_VmId.size()) ; ++ j) { - Frame3d frVzmF ; - bOkF = m_pGeomDB->GetGlobFrame( m_VmId[j], frVzmF) && bOkF ; - ExecLineVmill( m_VmId[j], i, m_VmTool[i].dTdOffs, m_VmTool[i].dAdOffs, - vPtNoseI[i], vVtDirI[i], vVtAuxI[i], vFrVzmI[j], ptNoseF, vtDirF, vtAuxF, frVzmF) ; + // se non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill + if ( nMoveType != 0 || ! NeedCollisionCheck()) { + for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) { + Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ; + bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ; + for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) { + Frame3d frVzmF ; + bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ; + ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs, + vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ; + // se ultimo utensile, salvo riferimento per prossimo inizio + if ( j == int( m_VmTool.size()) - 1) + vFrVzmI[k] = frVzmF ; + } + // aggiorno prossimo inizio + vPtNoseI[j] = ptNoseF ; + vVtDirI[j] = vtDirF ; + vVtAuxI[j] = vtAuxF ; } } + // eseguo eventuale collision check + bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ; } } // Eseguo movimento su arco @@ -1284,6 +1299,15 @@ Simulator::ExecLineVmill( int nVmId, int nCurrTool, double dVmTdOffs, double dVm ") Pf=(" + ToString( ptHfL) + ") Vf=(" + ToString( vtHfL) + ") Af=(" + ToString( vtAfL) + ")" ; LOG_DBG_INFO( GetEMkLogger(), sOut.c_str()) } + // Se utensile che non lavora di testa + if ( ! m_bCutOnTip) { + // se movimento di testa, non eseguo asportazione + Vector3d vtDirM = Media( vtHiL, vtHfL) ; + vtDirM.Normalize() ; + double dAxMove = ( ptHfL - ptHiL) * vtDirM ; + if ( dAxMove < -EPS_SMALL && dAxMove < -0.5 * abs( dAxMove)) + return true ; + } // Eseguo return pVZM->MillingStep( nCurrTool, ptHiL, vtHiL, vtAiL, ptHfL, vtHfL, vtAfL) ; } diff --git a/Simulator.h b/Simulator.h index 21808d5..3c340c6 100644 --- a/Simulator.h +++ b/Simulator.h @@ -158,6 +158,7 @@ class Simulator std::string m_sHead ; // nome della testa corrente int m_nExit ; // indice dell'uscita corrente double m_dTDiam ; // diametro dell'utensile corrente + bool m_bCutOnTip ; // flag capacità di lavorare di testa dell'utensile corrente INTVECTOR m_VmId ; // vettore identificativi Zmap per Virtual Milling INTVECTOR m_CdId ; // vettore identificativi Zmap per Collision Detection VMTVECTOR m_VmTool ; // vettore utensili attivi per virtual milling