diff --git a/SawRoughing.cpp b/SawRoughing.cpp index 27d6b50..e5a4a4a 100644 --- a/SawRoughing.cpp +++ b/SawRoughing.cpp @@ -60,6 +60,7 @@ using namespace std ; // 2652 = "Warning in SawRoughing : No machinable path" // 2653 = "Warning in SawRoughing : Tool name changed (xx)" // 2654 = "Warning in SawRoughing : Tool data changed (xx)" +// 2655 = "Warning in SawRoughing : Link not compatible with extension" //---------------------------------------------------------------------------- const string MCH_SECTION = "Sect" ; @@ -1093,6 +1094,11 @@ SawRoughing::CalculateToolPath( int nAuxId, int nPvId, int nClId) bool bExtend ; if ( ! GetValInNotes( m_Params.m_sUserNotes, UN_EXTEND, bExtend)) bExtend = true ; + // se estensione non presente e Link di tipoi Extended, lo forzo come Center + if ( ! bExtend && m_Params.m_nLeadLinkType == SAWROU_LL_OUT) { + m_pMchMgr->SetWarning( 2655, "Warning in SawRoughing : Link not compatible with extension") ; + m_Params.m_nLeadLinkType = SAWROU_LL_CENT ; + } // Recupero ed elaboro la linea guida Point3d ptGdStart, ptGdEnd ; @@ -1226,7 +1232,7 @@ SawRoughing::CalculateToolPath( int nAuxId, int nPvId, int nClId) if ( abs( ptEnd.x - ptStart.x) < EPS_SMALL) { vdVr.push_back( ( ptEnd.x + ptStart.x) / 2) ; vdVrDelta.push_back( ptEnd.y - ptStart.y) ; - } + } } // Determino le posizioni particolari @@ -1272,82 +1278,56 @@ SawRoughing::CalculateToolPath( int nAuxId, int nPvId, int nClId) for ( int j = 1 ; j < int( vdPp.size()) ; ++ j) { double dXmax = vdPp[j-1] ; double dXmin = vdPp[j] ; - - if ( m_Params.m_nStepType == SAWROU_ST_ZCONST) { - // le pareti verticali vanno trattate nell'intervallo della quota più bassa - bool bIncludeMax = ( vdPDelta[j-1] < EPS_SMALL) ; - bool bIncludeMin = ( vdPDelta[j] > - EPS_SMALL) ; - // verifico se devo trattare l'estremo a dXmax singolarmente - if ( j == 1 && ! bIncludeMax) { - if ( ! CalculateZConstCut( pCrv, dXmax, dXmax, true, false, ptGdStart, ptGdEnd, vtGdDir, frSect, pStmRaw, b3Raw, bExtend, dMaxDepth, - true, false, nCount)) - return false ; - } - // tratto l'intervallo - bool bFirstInterval = ( j == 1) && bIncludeMax ; - bool bLastInterval = ( j == vdPp.size() - 1) && bIncludeMin ; - if ( ! CalculateZConstCut( pCrv, dXmin, dXmax, bIncludeMax, bIncludeMin, ptGdStart, ptGdEnd, vtGdDir, frSect, pStmRaw, b3Raw, bExtend, dMaxDepth, - bFirstInterval, bLastInterval, nCount)) - return false ; - // verifico se devo trattare l'estremo a dXmin singolarmente - if ( j == vdPp.size() - 1 && ! bIncludeMin) { - if ( ! CalculateZConstCut( pCrv, dXmin, dXmin, false, true, ptGdStart, ptGdEnd, vtGdDir, frSect, pStmRaw, b3Raw, bExtend, dMaxDepth, - false, true, nCount)) - return false ; - } - } - else { - double dLargh = dXmax - dXmin ; - double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; - int nStep = max( 1, static_cast( ceil( dLargh / dStep))) ; - dStep = dLargh / nStep ; - double dSectYMin = b3Crv.GetMin().y ; - double dSectYMax = b3Crv.GetMax().y ; + double dLargh = dXmax - dXmin ; + double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; + int nStep = max( 1, static_cast( ceil( dLargh / dStep))) ; + dStep = dLargh / nStep ; + double dSectYMin = b3Crv.GetMin().y ; + double dSectYMax = b3Crv.GetMax().y ; - int nStart = ( j == 1 ? 0 : 1) ; - for ( int i = nStart ; i <= nStep ; ++ i) { - // flag per primo e ultimo taglio - bool bFirst = ( j == 1 && i == 0) ; - bool bLast = ( j == vdPp.size() - 1 && i == nStep) ; - // determino l'ascissa della prima intersezione - double dX = dXmax - i * dStep ; - // determino l'ordinata della prima intersezione - double dY ; - if ( ! GetHeightOnSection( pCrv, dX, dSectYMin, dSectYMax, dY)) + int nStart = ( j == 1 ? 0 : 1) ; + for ( int i = nStart ; i <= nStep ; ++ i) { + // flag per primo e ultimo taglio + bool bFirst = ( j == 1 && i == 0) ; + bool bLast = ( j == vdPp.size() - 1 && i == nStep) ; + // determino l'ascissa della prima intersezione + double dX = dXmax - i * dStep ; + // determino l'ordinata della prima intersezione + double dY ; + if ( ! GetHeightOnSection( pCrv, dX, dSectYMin, dSectYMax, dY)) + return false ; + // estremi del taglio + Vector3d vtMove = dX * frSect.VersX() + dY * frSect.VersY() - 0.5 * m_TParams.m_dThick * vtTool ; + Point3d ptStart = ptGdStart + vtMove ; + Point3d ptEnd = ptGdEnd + vtMove ; + // adatto la guida corrente al grezzo + AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw) ; + // determino l'elevazione del taglio + Vector3d vtThick = vtTool * m_TParams.m_dThick ; + double dElev, dElev2 ; + if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) || + ! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) { + m_pMchMgr->SetLastError( 2609, "Error in SawRoughing : GetElevation") ; + return false ; + } + dElev = max( dElev, dElev2) ; + // se elevazione nulla, verifico col massimo del grezzo + if ( dElev < EPS_SMALL) + dElev = max( 0., b3Raw.GetMax().z - ptStart.z) ; + // la confronto con il massimo affondamento e con la massima lavorazione della lama + if ( dElev > dMaxDepth) { + ptStart += Vector3d( 0, 0, dElev - dMaxDepth) ; + ptEnd += Vector3d( 0, 0, dElev - dMaxDepth) ; + dElev = dMaxDepth ; + } + // esecuzione del taglio + if ( m_Params.m_nStepType != SAWROU_ST_ZIGZAG) { + if ( ! CalculateOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, pStmRaw)) return false ; - // estremi del taglio - Vector3d vtMove = dX * frSect.VersX() + dY * frSect.VersY() - 0.5 * m_TParams.m_dThick * vtTool ; - Point3d ptStart = ptGdStart + vtMove ; - Point3d ptEnd = ptGdEnd + vtMove ; - // adatto la guida corrente al grezzo - AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw) ; - // determino l'elevazione del taglio - Vector3d vtThick = vtTool * m_TParams.m_dThick ; - double dElev, dElev2 ; - if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) || - ! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) { - m_pMchMgr->SetLastError( 2609, "Error in SawRoughing : GetElevation") ; + } + else { + if ( ! CalculateZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, nCount, pStmRaw)) return false ; - } - dElev = max( dElev, dElev2) ; - // se elevazione nulla, verifico col massimo del grezzo - if ( dElev < EPS_SMALL) - dElev = max( 0., b3Raw.GetMax().z - ptStart.z) ; - // la confronto con il massimo affondamento e con la massima lavorazione della lama - if ( dElev > dMaxDepth) { - ptStart += Vector3d( 0, 0, dElev - dMaxDepth) ; - ptEnd += Vector3d( 0, 0, dElev - dMaxDepth) ; - dElev = dMaxDepth ; - } - // esecuzione del taglio - if ( m_Params.m_nStepType != SAWROU_ST_ZIGZAG) { - if ( ! CalculateOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, b3Raw)) - return false ; - } - else { - if ( ! CalculateZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, nCount, b3Raw)) - return false ; - } } } } @@ -1781,7 +1761,7 @@ SawRoughing::AdaptGuideLineToRaw( Point3d& ptGdStart, Point3d& ptGdEnd, const Ve //---------------------------------------------------------------------------- bool SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, - const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, const BBox3d& b3Raw) + const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, const ISurfTriMesh* pStmRaw) { // recupero distanza di sicurezza double dSafeZ = GetSafeZ() ; @@ -1793,13 +1773,10 @@ SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, c if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) { // distanza XY tra centro e bordo taglio double dDeltaT = 0 ; - if ( dElev > 0.0 && dElev < 0.5 * m_TParams.m_dDiam) - dDeltaT = sqrt( dElev * m_TParams.m_dDiam - dElev * dElev) ; - // correzione per guida inclinata - Vector3d vtRef = Y_AX ; - if ( abs( ptStart.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptStart.y - b3Raw.GetMax().y) < EPS_SMALL) - vtRef = X_AX ; - dDeltaT += m_TParams.m_dThick * ( vtDir * vtRef) / ( vtDir ^ vtRef).Len() ; + if ( pStmRaw != nullptr) { + if ( ! GetElevation( m_nPhase, ptStart, vtTool, m_TParams.m_dDiam /2., m_TParams.m_dLen, dSafeZ, - vtDir, dDeltaT)) + return false ; + } // modifico inizio ptNewStart = ptStart - vtDir * ( dDeltaT + dAppr) ; } @@ -1867,7 +1844,7 @@ SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, c if ( AddLinearMove( ptP5) == GDB_ID_NULL) return false ; } - } + } // 4 -> retrazione if ( ! AddRetract( ptEnd, vtCorr, dSafeZ, dElev, dAppr)) return false ; @@ -1880,7 +1857,7 @@ SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, c bool SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, - int& nCount, const BBox3d& b3Raw) + int& nCount, const ISurfTriMesh* pStmRaw) { // recupero distanza di sicurezza double dSafeZ = GetSafeZ() ; @@ -1895,29 +1872,17 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c Vector3d vtNewDir = vtDir ; // se attacco/uscita/collegamento esterno allungo inizio e fine if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) { - // distanza XY tra centro e bordo taglio - double dDeltaT = 0 ; - if ( dElev > 0.0 && dElev < 0.5 * m_TParams.m_dDiam) - dDeltaT = sqrt( dElev * m_TParams.m_dDiam - dElev * dElev) ; - double dDeltaTSt = dDeltaT ; - double dDeltaTEn = dDeltaT ; - // calcolo correzione per guida inclinata per far fuoriuscire la lama di tutto lo spessore - // ricavo il lato di uscita dal grezzo dello start - Vector3d vtRef = Y_AX ; - if ( abs( ptStart.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptStart.y - b3Raw.GetMax().y) < EPS_SMALL) - vtRef = X_AX ; - dDeltaTSt += m_TParams.m_dThick * ( vtDir * vtRef) / ( vtDir ^ vtRef).Len() ; - // end - vtRef = Y_AX ; - if ( abs( ptEnd.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptEnd.y - b3Raw.GetMax().y) < EPS_SMALL) - vtRef = X_AX ; - dDeltaTEn += m_TParams.m_dThick * ( vtDir * vtRef) / ( vtDir ^ vtRef).Len() ; - + double dDeltaTSt = 0., dDeltaTEn = 0. ; + if ( pStmRaw != nullptr) { + if ( ! GetElevation( m_nPhase, ptStart, vtTool, m_TParams.m_dDiam / 2., m_TParams.m_dLen, dSafeZ, - vtDir, dDeltaTSt) || + ! GetElevation( m_nPhase, ptEnd, vtTool, m_TParams.m_dDiam / 2., m_TParams.m_dLen, dSafeZ, vtDir, dDeltaTEn)) + return false ; + } // modifico inizio ptNewStart = ptStart - vtDir * ( dDeltaTSt + dAppr) ; // modifico fine ptNewEnd = ptEnd + vtDir * ( dDeltaTEn + dAppr) ; - } + } // le passate dispari sono al contrario if ( ( nCount % 2) != 0) { swap( ptOriStart, ptOriEnd) ; @@ -1934,7 +1899,7 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c } // 2 -> movimento in affondo al punto iniziale SetFlag( 0) ; - // con attacco centrato sono sul materiale e devo usare feed di testa + // con attacco centrato sono sul materiale e devo usare feed di testa if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { SetFeed( GetTipFeed()) ; Point3d ptCurr ; GetCurrPos( ptCurr) ; @@ -1943,44 +1908,108 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c return false ; } } - // con attacco fuori sono in aria + // con attacco fuori else { + // se primo movimento if ( bFirst) { SetFeed( GetFeed()) ; if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) return false ; } + // altrimenti else { - Point3d ptLast ; - GetCurrPos( ptLast) ; + Point3d ptLast ; GetCurrPos( ptLast) ; double dDiff = ( ptNewStart - ptLast) * vtNewDir ; - // se precedente e corrente sono fuori allo stesso modo - if ( abs( dDiff) < 10 * EPS_SMALL) { - // inizio nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) - return false ; + // se precedente e corrente sono fuori allo stesso modo, inizio nuova passata + if ( abs( dDiff) < 10. * EPS_SMALL) { + // controllo se mi trovo dentro o fuori dal grezzo + double dElev = 0. ; + if ( GetElevation( m_nPhase, ptLast, ptNewStart, m_vtCorr, dElev) && dElev < EPS_SMALL) { + // fuori dal grezzo + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + else { + // dentro al grezzo + // -> movimento di risalita + SetFeed( GetEndFeed()) ; + Point3d ptAbove = ptLast + m_vtCorr * ( dElev + dSafeZ) ; + if ( AddLinearMove( ptAbove) == GDB_ID_NULL) + return false ; + // -> allineamento fuori dal grezzo + Vector3d vtDir = OrthoCompo( ( ptNewStart - ptAbove), m_vtCorr) ; + if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL) + return false ; + // -> discesa al nuovo punto iniziale + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } } // se il precedente è più fuori - else if ( dDiff > 0) { + else if ( dDiff > 0.) { // allungo nuova passata SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart - dDiff * vtNewDir) == GDB_ID_NULL) - return false ; + Point3d ptDest = ptNewStart - dDiff * vtNewDir ; + // controllo se mi trovo dentro o fuori dal grezzo + double dElev = 0. ; + if ( GetElevation( m_nPhase, ptLast, ptDest, m_vtCorr, dElev) && dElev < EPS_SMALL) { + // fuori dal grezzo + if ( AddLinearMove( ptDest) == GDB_ID_NULL) + return false ; + } + else { + // dentro al grezzo + // -> movimento di risaluta + SetFeed( GetEndFeed()) ; + Point3d ptAbove = ptLast + m_vtCorr * ( dElev + dSafeZ) ; + if ( AddLinearMove( ptAbove) == GDB_ID_NULL) + return false ; + // -> allineamento sopra al grezzo + Vector3d vtDir = OrthoCompo( ( ptDest - ptAbove), m_vtCorr) ; + if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL) + return false ; + // -> discesa al nuovo punto iniziale + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptDest) == GDB_ID_NULL) + return false ; + } } // se il corrente è più fuori else { // allungo passata precedente - if ( AddLinearMove( ptLast + dDiff * vtNewDir) == GDB_ID_NULL) - return false ; - // inizio nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + Point3d ptExtend = ptLast + dDiff * vtNewDir ; + if ( AddLinearMove( ptExtend) == GDB_ID_NULL) return false ; + // inizio nuova passata, controllo se mi trovo fuori dal grezzo + double dElev = 0. ; + if ( GetElevation( m_nPhase, ptExtend, ptNewStart, m_vtCorr, dElev) && dElev < EPS_SMALL) { + // fuori dal grezzo + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + else { + // dentro la grezzo + // -> movimento di risalita + SetFeed( GetEndFeed()) ; + Point3d ptAbove = ptExtend + m_vtCorr * ( dElev + dSafeZ) ; + if ( AddLinearMove( ptAbove) == GDB_ID_NULL) + return false ; + // -> allineamento fuori dal grezzo + Vector3d vtDir = OrthoCompo( ( ptNewStart - ptAbove), m_vtCorr) ; + if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL) + return false ; + // -> discesa al nuovo punto iniziale + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } } } } - // 3 -> movimento di lato al punto finale + // 3 -> movimento al punto finale if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { SetFeed( GetFeed()) ; if ( AddLinearMove( ptNewEnd) == GDB_ID_NULL) @@ -2036,32 +2065,95 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c return false ; } else { - Point3d ptLast ; - GetCurrPos( ptLast) ; + Point3d ptLast ; GetCurrPos( ptLast) ; double dDiff = ( ptNewStart - ptLast) * vtNewDir ; - // se precedente e corrente sono fuori allo stesso modo - if ( abs( dDiff) < 10 * EPS_SMALL) { - // inizio nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart + vtCorr * dDelta) == GDB_ID_NULL) - return false ; + // se precedente e corrente sono fuori allo stesso modo, inizio nulva passata + if ( abs( dDiff) < 10. * EPS_SMALL) { + Point3d ptDest = ptNewStart + vtCorr * dDelta ; + // controllo se mi trovo dentro o fuori dal grezzo + double dElev = 0. ; + if ( GetElevation( m_nPhase, ptLast, ptDest, m_vtCorr, dElev) && dElev < EPS_SMALL) { + // fuori dal grezzo + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptDest) == GDB_ID_NULL) + return false ; + } + else { + // dentro al grezzo + // -> movimento di risalita + SetFeed( GetEndFeed()) ; + Point3d ptAbove = ptLast + m_vtCorr * ( dElev + dSafeZ) ; + if ( AddLinearMove( ptAbove) == GDB_ID_NULL) + return false ; + // -> allinamento fuori dal grezzo + Vector3d vtDir = OrthoCompo( ( ptDest - ptAbove), m_vtCorr) ; + if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL) + return false ; + // -> disscesa al nuovo punto iniziale + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptDest) == GDB_ID_NULL) + return false ; + } } // se il precedente è più fuori - else if ( dDiff > 0) { + else if ( dDiff > 0.) { // allungo nuova passata SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart + vtCorr * dDelta - dDiff * vtNewDir) == GDB_ID_NULL) - return false ; + Point3d ptDest = ptNewStart + vtCorr * dDelta - dDiff * vtNewDir ; + // controllo se mi trovo dentro o fuori dal grezzo + if ( GetElevation( m_nPhase, ptLast, ptDest, m_vtCorr, dElev) && dElev < EPS_SMALL) { + // fuori dal grezzo + if ( AddLinearMove( ptDest) == GDB_ID_NULL) + return false ; + } + else { + // dentro al grezzo + // -> movimento di risalita + SetFeed( GetEndFeed()) ; + Point3d ptAbove = ptLast + m_vtCorr * ( dElev + dSafeZ) ; + if ( AddLinearMove( ptAbove) == GDB_ID_NULL) + return false ; + // -> allineamento sopra al grezzo + Vector3d vtDir = OrthoCompo( ( ptDest - ptAbove), m_vtCorr) ; + if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL) + return false ; + // -> discesa al nuovo punto iniziale + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptDest) == GDB_ID_NULL) + return false ; + } } // se il corrente è più fuori else { // allungo passata precedente - if ( AddLinearMove( ptLast + dDiff * vtNewDir) == GDB_ID_NULL) - return false ; - // inizio nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart + vtCorr * dDelta) == GDB_ID_NULL) + Point3d ptExtend = ptLast + dDiff * vtNewDir ; + if ( AddLinearMove( ptExtend) == GDB_ID_NULL) return false ; + // inizio nuova passata, controllo se mi trovo fuori dal grezzo + Point3d ptDest = ptNewStart + vtCorr * dDelta ; + double dElev = 0. ; + if ( GetElevation( m_nPhase, ptExtend, ptDest, m_vtCorr, dElev) && dElev < EPS_SMALL) { + // fuori dal grezzo + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptDest) == GDB_ID_NULL) + return false ; + } + else { + // dentro la grezzo + // -> movimento di risalita + SetFeed( GetEndFeed()) ; + Point3d ptAbove = ptExtend + m_vtCorr * ( dElev + dSafeZ) ; + if ( AddLinearMove( ptAbove) == GDB_ID_NULL) + return false ; + // -> allineamento fuori dal grezzo + Vector3d vtDir = OrthoCompo( ( ptDest - ptAbove), m_vtCorr) ; + if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL) + return false ; + // -> discesa al nuovo punto finale + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptDest) == GDB_ID_NULL) + return false ; + } } } } @@ -2088,7 +2180,7 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c swap( ptOriStart, ptOriEnd) ; vtNewDir.Invert() ; } - } + } // 4 -> retrazione if ( bLast || m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { if ( ! AddRetract( ptNewEnd, vtCorr, dSafeZ, dElev, dAppr)) @@ -2099,339 +2191,6 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c return true ; } -//---------------------------------------------------------------------------- -bool -SawRoughing::CalculateZConstCut( const ICurve* pCrv, double dXmin, double dXmax, bool bIncludeMax, bool bIncludeMin, - const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, const Frame3d& frSect, - const ISurfTriMesh* pStmRaw, const BBox3d& b3Raw, bool bExtend, double dDepth, - bool bFirstInterval, bool bLastInterval, int& nCount) -{ - // calcolo step orizzontali - double dLargh = dXmax - dXmin ; - double dSideStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; - int nSideStep = max( 1, static_cast( ceil( dLargh / dSideStep))) ; - dSideStep = dLargh / nSideStep ; - - // determino le coordinate x e y di tutte le intersezioni con la sezione ordinate per x decrescente - BBox3d b3Crv ; - pCrv->GetLocalBBox( b3Crv) ; - double dSectYMin = b3Crv.GetMin().y ; - double dSectYMax = b3Crv.GetMax().y ; - int nSize = nSideStep + ( bIncludeMax ? 1 : 0) + ( bIncludeMin ? 0 : -1) ; - DBLVECTOR vIntersX( nSize) ; - DBLVECTOR vIntersY( nSize) ; - int nStart = ( bIncludeMax ? 0 : 1) ; - int nEnd = ( bIncludeMin ? nSideStep : nSideStep - 1) ; - for ( int i = nStart ; i <= nEnd ; ++ i) { - vIntersX[i-nStart] = dXmax - i * dSideStep ; - if ( ! GetHeightOnSection( pCrv, vIntersX[i-nStart], dSectYMin, dSectYMax, vIntersY[i-nStart])) - return false ; - } - - // calcolo elevazione - double dTotElev = - INFINITO ; - double dRefQuote = 0 ; - for ( int i = 0 ; i < int( vIntersX.size()) ; i++) { - Vector3d vtMove = vIntersX[i] * frSect.VersX() + vIntersY[i] * frSect.VersY() - 0.5 * m_TParams.m_dThick * m_vtTool ; - Vector3d vtThick = m_vtTool * m_TParams.m_dThick ; - Point3d ptStart = ptGdStart + vtMove ; - Point3d ptEnd = ptGdEnd + vtMove ; - Point3d ptStart2 = ptStart + vtThick ; - Point3d ptEnd2 = ptEnd + vtThick ; - AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw) ; - AdaptGuideLineToRaw( ptStart2, ptEnd2, vtGdDir, bExtend, pStmRaw) ; - - // determino l'elevazione del taglio - double dCurrElev1, dCurrElev2 ; - if ( ! GetElevation( m_nPhase, ptStart, ptEnd, m_vtCorr, dCurrElev1) || - ! GetElevation( m_nPhase, ptStart2, ptEnd2, m_vtCorr, dCurrElev2)) { - m_pMchMgr->SetLastError( 2609, "Error in SawRoughing : GetElevation") ; - return false ; - } - double dCurrElev = max( dCurrElev1, dCurrElev2) ; - if ( dCurrElev > dTotElev) { - dTotElev = dCurrElev ; - dRefQuote = vIntersY[i] ; - } - else if ( abs( dCurrElev - dTotElev) < EPS_SMALL && dRefQuote > vIntersY[i]) - dRefQuote = vIntersY[i] ; - } - // eventuale correzione con depth - double dRealElev = min( dTotElev, dDepth) ; - - // calcolo step verticali - int nStep = ( m_Params.m_dStep < EPS_SMALL ? 1 : static_cast( ceil( dRealElev / m_Params.m_dStep))) ; - nStep = max( 1, nStep) ; - double dStep = dRealElev / nStep ; - - // costruisco un vettore con le quote di lavoro e gli indici delle ascisse in vIntersX da lavorare a quella quota - vector> vStepCoord ; - vStepCoord.reserve( nStep) ; - for ( int j = 1 ; j <= nStep ; j++) { - vStepCoord.emplace_back( dRefQuote + dTotElev - j * dStep, INTVECTOR()) ; - vStepCoord.back().second.reserve( vIntersX.size()) ; - for ( int i = 0 ; i < int( vIntersX.size()) ; i ++) { - // l'ascissa va considerata solo se la quota di lavoro è maggiore di quella della sezione - if ( vStepCoord.back().first > vIntersY[i] - EPS_SMALL) - vStepCoord.back().second.emplace_back(i) ; - } - // se non ci sono punti da lavorare alla quota corrente la scarto - if ( vStepCoord.back().second.empty()) - vStepCoord.pop_back() ; - } - - // individuo piani orizzontali extra da lavorare - int nStartSearch = vStepCoord.size() ; - const ICurveComposite* pCompo = GetCurveComposite( pCrv) ; - if ( pCompo != nullptr) { - for ( int i = 0 ; i < pCompo->GetCurveCount() ; i++) { - const ICurve* pSimpCrv = pCompo->GetCurve( i) ; - Point3d ptStart, ptEnd ; - pSimpCrv->GetStartPoint( ptStart) ; - pSimpCrv->GetEndPoint( ptEnd) ; - // verifico se è nell'intervallo da lavorare - if ( ptEnd.x > dXmax - EPS_SMALL) - continue ; - if ( ptStart.x < dXmin + EPS_SMALL) - break ; - - // verifico se tratto orizzontale - if ( abs( ptEnd.y - ptStart.y) < EPS_SMALL) { - double dY = ( ptEnd.y + ptStart.y) / 2 ; - // se sotto la quota minima di lavoro lo ignoro - if ( dY < dRefQuote + dTotElev - dRealElev - EPS_SMALL) - continue ; - // se quota già considerata negli step ( ovvero è multiplo di dStep) la ignoro - if ( dStep < EPS_SMALL) { - if ( abs( dRefQuote + dTotElev - dY) < EPS_SMALL) - continue ; - } - else { - double dRes = ( dRefQuote + dTotElev - dY) / dStep ; - if ( dRes > EPS_SMALL && abs( dRes - round( dRes)) < EPS_SMALL) - continue ; - } - - // verifico se piano orizzontale già individuato tra i piani extra - auto it = find_if( vStepCoord.begin() + nStartSearch, vStepCoord.end(), [dY]( const pair& a) - { return abs( a.first - dY) < EPS_SMALL ;}) ; - // se non individuato lo aggiungo - if ( it == vStepCoord.end()) { - vStepCoord.emplace_back( dY, INTVECTOR()) ; - vStepCoord.back().second.reserve( vIntersX.size()) ; - it = vStepCoord.end() - 1 ; - } - // calcolo le ascisse da lavorare corrispondenti al piano - for ( int j = 0 ; j < int( vIntersX.size()) ; j ++) { - if ( vIntersX[j] < ptEnd.x - EPS_SMALL) - break ; - if ( vIntersX[j] < ptStart.x + EPS_SMALL && vIntersX[j] > ptEnd.x - EPS_SMALL) - it->second.emplace_back( j) ; - } - // se non ci sono punti da lavorare lo ignoro - if ( it->second.empty()) - vStepCoord.pop_back() ; - } - } - } - - // riordino per quota di lavoro decrescente - sort( vStepCoord.begin(), vStepCoord.end(), []( const pair& a, const pair& b) - { return a.first > b.first ;}) ; - - // recupero distanza di sicurezza - double dSafeZ = GetSafeZ() ; - // lunghezza di approccio/retrazione - double dAppr = m_Params.m_dStartPos ; - - double dLastX = 0 ; - double dElev = 0 ; - Point3d ptNewEnd ; - - // ciclo sugli step verticali - for ( int j = 0 ; j < int( vStepCoord.size()) ; j++) { - - // inverto lo step corrente se lo step precedente finisce più vicino all'ultima ascissa corrente - bool bInvertStep = false ; - if ( j > 0) { - double dXStepMax = vIntersX[vStepCoord[j].second.front()] ; - double dXStepMin = vIntersX[vStepCoord[j].second.back()] ; - if ( abs( dXStepMin - dLastX) < abs( dXStepMax - dLastX)) - bInvertStep = true ; - } - - // ciclo sui punti orizzontali - for ( int i = 0 ; i < int( vStepCoord[j].second.size()) ; ++ i) { - - // se lo step è invertito leggo dal fondo - int nI = ( bInvertStep ? vStepCoord[j].second.size() - i - 1 : i) ; - // indice da considerare nel vettore delle coordinate - int nIdx = vStepCoord[j].second[nI] ; - - bool bFirst = ( bFirstInterval && j == 0 && i == 0) ; - bool bLast = ( bLastInterval && j == vStepCoord.size() - 1 && i == vStepCoord[j].second.size() - 1) ; - bool bAlignedPoints = abs( dLastX - vIntersX[nIdx]) < EPS_SMALL ; - - // 0 -> retrazione del precedente - if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { - // se punto intermedio dello step corrente va sempre aggiunta - if ( i > 0) { - if ( ! AddRetract( ptNewEnd, m_vtCorr, dSafeZ, dElev, dAppr)) - return false ; - } - // se il punto è il primo dello step corrente va aggiunta solo se non è allineato con l'ultimo punto - // dello step precedente ( se allineati è semplice discesa senza rialzarsi) - else if ( j > 0 && ! bAlignedPoints) { - if ( ! AddRetract( ptNewEnd, m_vtCorr, dSafeZ, dElev, dAppr)) - return false ; - } - } - - // calcolo punti di riferimento della guida alla quota della sezione - dLastX = vIntersX[nIdx] ; - double dY = vIntersY[nIdx] ; - Vector3d vtMove = dLastX * frSect.VersX() + dY * m_vtCorr - 0.5 * m_TParams.m_dThick * m_vtTool ; - Point3d ptStart = ptGdStart + vtMove ; - Point3d ptEnd = ptGdEnd + vtMove ; - // adatto la guida corrente al grezzo - AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw) ; - - // quantità necessaria per arrivare alla quota di lavoro dalla quota della sezione - double dDelta = vStepCoord[j].first - dY ; - // vera elevazione alla quota della sezione - dElev = max( 0.0, dRefQuote + dTotElev - dY) ; - - Point3d ptOriStart = ptStart ; - Point3d ptOriEnd = ptEnd ; - Point3d ptNewStart = ptOriStart ; - ptNewEnd = ptOriEnd ; - Vector3d vtNewDir = vtGdDir ; - - // se attacco/uscita/collegamento esterno allungo inizio e fine - if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) { - // distanza XY tra centro e bordo taglio - double dCurrElev = dElev - dDelta ; - double dDeltaT = 0 ; - if ( dCurrElev > 0.0 && dCurrElev < 0.5 * m_TParams.m_dDiam) - dDeltaT = sqrt( dCurrElev * m_TParams.m_dDiam - dCurrElev * dCurrElev) ; - double dDeltaTSt = dDeltaT ; - double dDeltaTEn = dDeltaT ; - // calcolo correzione per guida inclinata per far fuoriuscire la lama di tutto lo spessore - // ricavo il lato di uscita dal grezzo dello start - Vector3d vtRef = Y_AX ; - if ( abs( ptStart.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptStart.y - b3Raw.GetMax().y) < EPS_SMALL) - vtRef = X_AX ; - dDeltaTSt += m_TParams.m_dThick * ( vtGdDir * vtRef) / ( vtGdDir ^ vtRef).Len() ; - // end - vtRef = Y_AX ; - if ( abs( ptEnd.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptEnd.y - b3Raw.GetMax().y) < EPS_SMALL) - vtRef = X_AX ; - dDeltaTEn += m_TParams.m_dThick * ( vtGdDir * vtRef) / ( vtGdDir ^ vtRef).Len() ; - - // modifico inizio - ptNewStart = ptOriStart - vtNewDir * ( dDeltaTSt + dAppr) ; - // modifico fine - ptNewEnd = ptOriEnd + vtNewDir * ( dDeltaTEn + dAppr) ; - } - - // le passate dispari sono al contrario - if ( ( nCount % 2) != 0) { - swap( ptOriStart, ptOriEnd) ; - swap( ptNewStart, ptNewEnd) ; - vtNewDir.Invert() ; - } - - // 1 -> approccio - if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { - // se collegamento interno va fatto se è un intermedio, se è il primo del primo step oppure - // se è il primo di uno step intermedio ma non è allineato allo step precedente - if ( i > 0 || ( i == 0 && j == 0) || ( i == 0 && j > 0 && ! bAlignedPoints)) - if ( ! AddApproach( ptNewStart, m_vtCorr, bFirst, dSafeZ, dElev, dAppr)) - return false ; - } - // se collegamento out va fatto solo se è il primo in assoluto - else if ( bFirst) - if ( ! AddApproach( ptNewStart, m_vtCorr, bFirst, dSafeZ, dElev, dAppr)) - return false ; - - // 2 -> movimento in affondo al punto iniziale - // con attacco centrato sono sul materiale e devo usare feed di testa - if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { - SetFlag( 0) ; - SetFeed( GetTipFeed()) ; - Point3d ptP2 = ptNewStart + m_vtCorr * dDelta ; - if ( AddLinearMove( ptP2) == GDB_ID_NULL) - return false ; - } - // con attacco fuori sono in aria - else { - if ( bFirst) { - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart + m_vtCorr * dDelta) == GDB_ID_NULL) - return false ; - } - else { - Point3d ptLast ; - GetCurrPos( ptLast) ; - double dDiff = ( ptNewStart - ptLast) * vtNewDir ; - // se precedente e corrente sono fuori allo stesso modo - if ( abs( dDiff) < 10 * EPS_SMALL) { - // inizio nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart + m_vtCorr * dDelta) == GDB_ID_NULL) - return false ; - } - // se il precedente è più fuori - else if ( dDiff > 0) { - // allungo nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart + m_vtCorr * dDelta - dDiff * vtNewDir) == GDB_ID_NULL) - return false ; - } - // se il corrente è più fuori - else { - // allungo passata precedente - if ( AddLinearMove( ptLast + dDiff * vtNewDir) == GDB_ID_NULL) - return false ; - // inizio nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart + m_vtCorr * dDelta) == GDB_ID_NULL) - return false ; - } - } - } - - // 3 -> movimento di lato al punto finale - if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) { - SetFeed( GetFeed()) ; - Point3d ptP3 = ptNewEnd + m_vtCorr * dDelta ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) - return false ; - } - else { - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptOriEnd + m_vtCorr * dDelta) == GDB_ID_NULL) - return false ; - SetFeed( GetEndFeed()) ; - if ( AddLinearMove( ptNewEnd + m_vtCorr * dDelta) == GDB_ID_NULL) - return false ; - } - - // 4 -> retrazione soltanto se ultimo in assoluto oppure se attacco interno e ultimo dell'ultimo step - if ( bLast || - ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT && j == vStepCoord.size() - 1 && i == vStepCoord[j].second.size() - 1)) { - if ( ! AddRetract( ptNewEnd, m_vtCorr, dSafeZ, dElev, dAppr)) - return false ; - } - - // incremento contatore passate - ++ nCount ; - } - } - - return true ; -} - //---------------------------------------------------------------------------- bool SawRoughing::CalculateCurvedZigZagCut( const ICurve* pCut, const Vector3d& vtTool, double dElev, bool bFirst, bool bLast, diff --git a/SawRoughing.h b/SawRoughing.h index ccb66e3..bffc30b 100644 --- a/SawRoughing.h +++ b/SawRoughing.h @@ -89,16 +89,12 @@ class SawRoughing : public Machining bool CalculateGuideLine( int nGuideId, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir) const ; bool AdaptGuideLineToRaw( Point3d& ptGdStart, Point3d& ptGdEnd, const Vector3d& vtGdDir, bool bExtend, const ISurfTriMesh* pStmRaw) const ; bool CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, - const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, const BBox3d& b3Raw) ; + const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, const ISurfTriMesh* pStmRaw) ; bool CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, - int& nCount, const BBox3d& b3Raw) ; - bool CalculateZConstCut( const ICurve* pCrv, double dXmin, double dXmax, bool bIncludeMax, bool bIncludeMin, - const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, const Frame3d& frSect, - const ISurfTriMesh* pStmRaw, const BBox3d& b3Raw, bool bExtend, double dDepth, - bool bFirstInterval, bool bLastInterval, int& nCount) ; + int& nCount, const ISurfTriMesh* pStmRaw) ; bool CalculateCurvedZigZagCut( const ICurve* pCut, const Vector3d& vtTool, double dElev, bool bFirst, bool bLast, - int& nCount) ; + int& nCount) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtCorr, bool bFirst, double dSafeZ, double dElev, double dAppr) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) ;