From 9d40a6a76667bfab727d302baeff9f98bd67d876 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 8 Dec 2020 16:51:05 +0000 Subject: [PATCH] EgtMachKernel : - correzioni varie a lavorazione Waterjetting per angoli interni. --- WaterJetting.cpp | 137 ++++++++++++++++++++++++++++++++++++++++------- WaterJetting.h | 1 + 2 files changed, 119 insertions(+), 19 deletions(-) diff --git a/WaterJetting.cpp b/WaterJetting.cpp index 88ba474..6353978 100644 --- a/WaterJetting.cpp +++ b/WaterJetting.cpp @@ -62,7 +62,8 @@ using namespace std ; // 3255 = "Warning in WaterJetting : skipped Path too short" //---------------------------------------------------------------------------- -const double EXTRA_ACC_LEN = 0.1 ; +const double EXTRA_ACC_LEN = 0.5 ; +const double INTANG_ROT_LEN = 5.0 ; //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_WATERJETTING), WaterJetting) ; @@ -1561,6 +1562,9 @@ WaterJetting::ProcessPath( int nPathId, int nPvId, int nClId) // Imposto dati comuni SetPathId( nPxId) ; + // Sistemazioni per angoli interni + AdjustPathForInternalAngles( pCompo) ; + // Inserisco la lavorazione if ( ! AddStandardWj( pCompo, vtTool, bSplitArcs)) return false ; @@ -1933,6 +1937,95 @@ WaterJetting::AddLoopsPreview( const ICurveComposite* pCompo, ISurfFlatRegion* p return true ; } +//---------------------------------------------------------------------------- +bool +WaterJetting::AdjustPathForInternalAngles( ICurveComposite* pCompo) +{ + // necessario aggiustamento solo se angolo di fianco positivo + if ( m_Params.m_dSideAngle < EPS_ANG_SMALL) + return true ; + // larghezza della lavorazione + double dW = m_dElev * sin( m_Params.m_dSideAngle * DEGTORAD) ; + // ciclo su tutte le entità + int nMaxInd = pCompo->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pCompo->GetCurve( i) ; + // dati eventuale entità precedente + const ICurve* pCrvP = nullptr ; + bool bPrevIntAng = false ; + double dPrevAng = 0 ; + double dPrevLen = 0 ; + if ( i > 0) { + // direzione finale precedente + pCrvP = pCompo->GetCurve( i - 1) ; + Vector3d vtEnd ; pCrvP->GetEndDir( vtEnd) ; + // direzione iniziale corrente + Vector3d vtStart ; pCrvC->GetStartDir( vtStart) ; + // angolo tra le direzioni + vtEnd.GetAngleXY( vtStart, dPrevAng) ; + // verifica di angolo interno + bPrevIntAng = IsInternalAngle( dPrevAng) ; + // lunghezza + pCrvP->GetLength( dPrevLen) ; + } + // dati eventuale entità successiva + const ICurve* pCrvN = nullptr ; + bool bNextIntAng = false ; + double dNextAng = 0 ; + double dNextLen = 0 ; + if ( i < nMaxInd) { + // direzione finale corrente + Vector3d vtEnd ; pCrvC->GetEndDir( vtEnd) ; + // direzione iniziale successiva + pCrvN = pCompo->GetCurve( i + 1) ; + Vector3d vtStart ; pCrvN->GetStartDir( vtStart) ; + // angolo tra le direzioni + vtEnd.GetAngleXY( vtStart, dNextAng) ; + // se angolo interno + bNextIntAng = IsInternalAngle( dNextAng) ; + // lunghezza + pCrvN->GetLength( dNextLen) ; + } + // se c'è angolo interno con la precedente + if ( bPrevIntAng) { + // lunghezza entità + double dLen ; pCrvC->GetLength( dLen) ; + // verifico lunghezza minima + double dSlowLen = dW / tan( ( 180 - abs( dPrevAng)) / 2 * DEGTORAD) ; + double dExtraLen = dSlowLen + INTANG_ROT_LEN - dLen ; + if ( dExtraLen > 0) { + // se entità successiva è in tangenza e abbastanza lunga, allungo la corrente a scapito della successiva + if ( ! bNextIntAng && dNextLen > dExtraLen) { + double dU ; Point3d ptP ; + if ( pCrvN->GetParamAtLength( dExtraLen, dU) && + pCrvN->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) + pCompo->ModifyJoint( i + 1, ptP) ; + } + } + } + // se c'è angolo interno con l'entità successiva + if ( bNextIntAng) { + // lunghezza entità + double dLen ; pCrvC->GetLength( dLen) ; + // verifico lunghezza minima + double dSlowLen = dW / tan( ( 180 - abs( dNextAng)) / 2 * DEGTORAD) ; + double dExtraLen = dSlowLen + INTANG_ROT_LEN - dLen ; + if ( dExtraLen > 0) { + // se entità precedente è in tangenza e abbastanza lunga, allungo la corrente a scapito della precedente + if ( ! bPrevIntAng && dPrevLen > dExtraLen) { + double dU ; Point3d ptP ; + if ( pCrvP->GetParamAtLength( dPrevLen - dExtraLen, dU) && + pCrvP->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) + pCompo->ModifyJoint( i, ptP) ; + } + } + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTool, bool bSplitArcs) @@ -1995,8 +2088,8 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo // angolo tra le direzioni double dAng ; vtEnd.GetAngleXY( vtStart, dAng) ; - // Se richiesto anello esterno e angolo esterno con precedente - if ( m_Params.m_nExtCornerType == WJET_EC_LOOP && IsExternalAngle( dAng)) { + // Se angolo esterno e richiesto anello esterno + if ( IsExternalAngle( dAng) && m_Params.m_nExtCornerType == WJET_EC_LOOP) { // lunghezza tratti lineari e loro punti estremi double dTgLen = 0.5 * m_TParams.m_dDiam * tan( 0.5 * dAng * DEGTORAD) ; Point3d ptP ; pCrvC->GetStartPoint( ptP) ; @@ -2020,8 +2113,8 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo if ( AddLinearMove( ptP) == GDB_ID_NULL) return false ; } - // se altrimenti richiesto rallentamento esterno e angolo esterno, eseguo accelerazione - else if ( m_Params.m_nExtCornerType == WJET_EC_SLOW && IsExternalAngle( dAng)) { + // se angolo esterno e richiesto rallentamento esterno, eseguo accelerazione + else if ( IsExternalAngle( dAng) && m_Params.m_nExtCornerType == WJET_EC_SLOW) { // lunghezza entità double dLen ; pCrvC->GetLength( dLen) ; // lunghezza di accelerazione @@ -2042,23 +2135,26 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo dUprev = dU ; } } - // se richiesto rallentamento interno e angolo interno, eseguo accelerazione e interpolazione direzione utensile - if ( m_Params.m_nIntCornerType == WJET_IC_SLOW && IsInternalAngle( dAng)) { + // se angolo interno, spezzo per interpolazione direzione utensile e se necessario aggiungo accelerazione + else if ( IsInternalAngle( dAng)) { + // flag di rallentamento + bool bReduceFeed = ( m_Params.m_nIntCornerType == WJET_IC_SLOW) ; // lunghezza entità double dLen ; pCrvC->GetLength( dLen) ; + double dFreeLen = dLen ; // lunghezza di accelerazione - double dAccLen = min( m_Params.m_dCornerSlowLen, dLen / 2 - EXTRA_ACC_LEN) ; + double dAccLen = min( dFreeLen - EXTRA_ACC_LEN, ( bReduceFeed ? m_Params.m_dCornerSlowLen : INTANG_ROT_LEN)) ; if ( m_Params.m_dSideAngle > 0) { double dW = m_dElev * sin( m_Params.m_dSideAngle * DEGTORAD) ; double dSlowLen = dW / tan( ( 180 - abs( dAng)) / 2 * DEGTORAD) ; - if ( dSlowLen > dLen / 2 - EXTRA_ACC_LEN) { + if ( dSlowLen > dFreeLen - EXTRA_ACC_LEN) { m_pMchMgr->SetLastError( 3204, "Error in WaterJetting : entity too small near inside corner") ; return false ; } - dAccLen = min( dSlowLen + m_Params.m_dCornerSlowLen, dLen / 2 - EXTRA_ACC_LEN) ; + dAccLen = min( dSlowLen + m_Params.m_dCornerSlowLen, dFreeLen - EXTRA_ACC_LEN) ; } // Feed ridotta - double dMinFeed = GetActualReducedFeed() ; + double dMinFeed = ( bReduceFeed ? GetActualReducedFeed() : GetActualFeed()) ; // Direzioni utensile nell'angolo e finale double dUsta = 0 ; double dUend ; pCrvC->GetParamAtLength( dAccLen, dUend) ; @@ -2096,8 +2192,8 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo Vector3d vtStart ; pCrvN->GetStartDir( vtStart) ; // angolo tra le direzioni double dAng ; vtEnd.GetAngleXY( vtStart, dAng) ; - // se richiesto rallentamento esterno e angolo esterno, aggiungo decelerazione - if ( m_Params.m_nExtCornerType == WJET_EC_SLOW && IsExternalAngle( dAng)) { + // se angolo esterno e richiesto rallentamento esterno, aggiungo decelerazione + if ( IsExternalAngle( dAng) && m_Params.m_nExtCornerType == WJET_EC_SLOW) { // lunghezza entità double dLen ; pCrvC->GetLength( dLen) ; // lunghezza di decelerazione @@ -2119,23 +2215,26 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo } dNextFeed = dMinFeed ; } - // se richiesto rallentamento interno e angolo interno, aggiungo decelerazione e interpolazione direzione utensile - if ( m_Params.m_nIntCornerType == WJET_IC_SLOW && IsInternalAngle( dAng)) { + // se angolo interno, spezzo per interpolazione direzione utensile e se necessario aggiungo decelerazione + else if ( IsInternalAngle( dAng)) { + // flag di rallentamento + bool bReduceFeed = ( m_Params.m_nIntCornerType == WJET_IC_SLOW) ; // lunghezza entità double dLen ; pCrvC->GetLength( dLen) ; + double dFreeLen = dLen * ( 1 - dUprev) ; // lunghezza di decelerazione - double dAccLen = min( m_Params.m_dCornerSlowLen, dLen / 2 - EXTRA_ACC_LEN) ; + double dAccLen = min( dFreeLen - EXTRA_ACC_LEN, ( bReduceFeed ? m_Params.m_dCornerSlowLen : INTANG_ROT_LEN)) ; if ( m_Params.m_dSideAngle > 0) { double dW = m_dElev * sin( m_Params.m_dSideAngle * DEGTORAD) ; double dSlowLen = dW / tan( ( 180 - abs( dAng)) / 2 * DEGTORAD) ; - if ( dSlowLen > dLen / 2 - EXTRA_ACC_LEN) { + if ( dSlowLen > dFreeLen - EXTRA_ACC_LEN) { m_pMchMgr->SetLastError( 3204, "Error in WaterJetting : entity too small near inside corner") ; return false ; } - dAccLen = min( dSlowLen + m_Params.m_dCornerSlowLen, dLen / 2 - EXTRA_ACC_LEN) ; + dAccLen = min( dSlowLen + m_Params.m_dCornerSlowLen, dFreeLen - EXTRA_ACC_LEN) ; } // Feed ridotta - double dMinFeed = GetActualReducedFeed() ; + double dMinFeed = ( bReduceFeed ? GetActualReducedFeed() : GetActualFeed()) ; // Direzioni utensile iniziale e nell'angolo double dUsta ; pCrvC->GetParamAtLength( dLen - dAccLen, dUsta) ; double dUend = 1 ; diff --git a/WaterJetting.h b/WaterJetting.h index 3b0c8f8..5fe5b05 100644 --- a/WaterJetting.h +++ b/WaterJetting.h @@ -74,6 +74,7 @@ class WaterJetting : public Machining bool Chain( int nGrpDestId) ; bool VerifySideAngle( void) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; + bool AdjustPathForInternalAngles( ICurveComposite* pCompo) ; bool GeneratePreView( int nPathId, const ICurveComposite* pCompo, double dAddedOverlap) ; bool AddLeadInPreview( const ICurveComposite* pCompo, ISurfFlatRegion* pSPV) ; bool AddLeadOutPreview( const ICurveComposite* pCompo, ISurfFlatRegion* pSPV) ;