diff --git a/Milling.cpp b/Milling.cpp index 7fee94e..deffecc 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -4217,6 +4217,22 @@ Milling::AdjustTabsParams( const ICurve* pCrv, bool& bPathTabsEnable, TabData& t return true ; } +//---------------------------------------------------------------------------- +static void +PeriodicIntervalsSubract( Intervals& ivItv, double dPeriod, double dMin, double dMax) +{ + if ( dMin < - EPS_SMALL) { + ivItv.Subtract( dPeriod + dMin, dPeriod) ; + dMin = 0 ; + } + if ( dMax > dPeriod + EPS_SMALL) { + ivItv.Subtract( dMin, dPeriod) ; + dMax -= dPeriod ; + } + if ( dMin < dMax) + ivItv.Subtract( dMin, dMax) ; +} + //---------------------------------------------------------------------------- bool Milling::CalcTabsPositions( const ICurveComposite* pCompo, bool bPathTabsEnable, const TabData& tdTabs, DBLVECTOR& vdTabs) @@ -4238,26 +4254,55 @@ Milling::CalcTabsPositions( const ICurveComposite* pCompo, bool bPathTabsEnable, if ( vtExtr.IsSmall()) vtExtr = Z_AX ; -#if 0 // determinazione intervalli validi Intervals ivTabs ; - // inizializzo intervallo valido - ivTabs.Set( 0, dLen) ; - // elimino le zone vicine agli angoli + // inizializzo intervallo valido (non sono ammessi tab a cavallo di inizio/fine) + ivTabs.Set( 0, dLen - dTabLen) ; + // elimino le zone con piccolo raggio e quelle vicine agli angoli + const double RAD_MIN = 100 ; + const double CORNER_RAG = 2 ; + const double CORNER_ANG = 5 ; + const double CORNER_DIST = 2 ; bool bContinue = true ; - double dCurrLen = 0 ; + double dJointLen = 0 ; const ICurve* pCurrCrv = pCompo->GetFirstCurve() ; const ICurve* pNextCrv = pCompo->GetNextCurve() ; while ( pNextCrv != nullptr) { - // aggiorno lunghezza - double dTmp = 0 ; - pCurrCrv->GetLength( dTmp) ; - dCurrLen += dTmp ; + // calcolo lunghezza entità + double dEntLen = 0 ; + pCurrCrv->GetLength( dEntLen) ; + // se arco, verifico se spigolo o inferiore a raggio minimo + const ICurveArc* pArc = GetCurveArc( pCurrCrv) ; + if ( pArc != nullptr) { + // determino il raggio sul profilo + bool bCCW = ( pArc->GetAngCenter() > 0) ; + double dRad = pArc->GetRadius() ; + if ( m_Params.m_nWorkSide == MILL_WS_LEFT) + dRad += m_TParams.m_dDiam / 2 * ( bCCW ? 1 : -1) ; + else if ( m_Params.m_nWorkSide == MILL_WS_RIGHT) + dRad += m_TParams.m_dDiam / 2 * ( bCCW ? -1 : 1) ; + // se raggio molto piccolo è uno spigolo + if ( dRad < CORNER_RAG) { + double dMin = dJointLen - CORNER_DIST - dTabLen ; + double dMax = dJointLen + dEntLen + CORNER_DIST ; + PeriodicIntervalsSubract( ivTabs, dLen, dMin, dMax) ; + } + // se raggio è piccolo + else if ( dRad < RAD_MIN) { + double dMin = dJointLen - dTabLen ; + double dMax = dJointLen + dEntLen ; + PeriodicIntervalsSubract( ivTabs, dLen, dMin, dMax) ; + } + } + // aggiorno lunghezza alla giunzione con la successiva + dJointLen += dEntLen ; // verifico se angolo tra le entità Vector3d vtTg1 ; pCurrCrv->GetEndDir( vtTg1) ; - Vector3d vtTg2 ; pCurrCrv->GetStartDir( vtTg2) ; - if ( abs( ( vtTg1 ^ vtTg2) * vtExtr) > sin( 5 * DEGTORAD)) { - + Vector3d vtTg2 ; pNextCrv->GetStartDir( vtTg2) ; + if ( abs( ( vtTg1 ^ vtTg2) * vtExtr) > sin( CORNER_ANG * DEGTORAD)) { + double dMin = dJointLen - CORNER_DIST - dTabLen ; + double dMax = dJointLen + CORNER_DIST ; + PeriodicIntervalsSubract( ivTabs, dLen, dMin, dMax) ; } // passo al successivo pCurrCrv = pNextCrv ; @@ -4268,26 +4313,29 @@ Milling::CalcTabsPositions( const ICurveComposite* pCompo, bool bPathTabsEnable, } } - // elimino parti (test) - if ( dLen > 300) { - ivTabs.Subtract( 0, 100) ; - ivTabs.Subtract( dLen - 100, dLen) ; - } - else { - ivTabs.Subtract( 0.4 * dLen, 0.6 * dLen) ; - } -#endif - // determino posizioni di inizio dei Tabs + double dLastIns = -1 - 2 * dTabLen ; double dNextTab = 0.5 * tdTabs.m_dBottomLen ; double dCurrLen = 0 ; while ( dCurrLen + dNextTab < dLen) { - vdTabs.emplace_back( dCurrLen + dNextTab) ; + double dPos = dCurrLen + dNextTab ; + double dPrev, dNext ; + if ( ivTabs.IsInside( dPos)) { + vdTabs.emplace_back( dPos) ; + dLastIns = dPos ; + } + else if ( ivTabs.GetPrevNearest( dPos, dPrev) && dPrev > dLastIns + 1.5 * dTabLen) { + vdTabs.emplace_back( dPrev) ; + dLastIns = dPrev ; + } + else if ( ivTabs.GetNextNearest( dPos, dNext) && dNext > dLastIns + dTabLen) { + vdTabs.emplace_back( dNext) ; + dLastIns = dNext ; + } dCurrLen += dNextTab + dTabLen ; dNextTab = tdTabs.m_dBottomLen ; } - if ( ! vdTabs.empty()) - vdTabs.emplace_back( dLen + m_dAddedOverlap + 100.) ; + vdTabs.emplace_back( dLen + m_dAddedOverlap + 100.) ; return true ; }