diff --git a/WaterJetting.cpp b/WaterJetting.cpp index 62bc205..37a73fc 100644 --- a/WaterJetting.cpp +++ b/WaterJetting.cpp @@ -2266,6 +2266,8 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo { // numero punti di accelerazione/decelerazione const int ACC_PNT_NUM = 7 ; + // valori limite per gestione degli angoli + const double LEN_TOL = 100 * EPS_SMALL ; // recupero distanze di sicurezza double dSafeZ = GetSafeZ() ; @@ -2287,6 +2289,7 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false ; + double dLen ; pCurve->GetLength( dLen) ; double dUprev = 0 ; bool bSlowFull = false ; // modalità speciale per angoli interni con rallentamento uniforme su tutta l'entità // se prima entità, approccio e affondo @@ -2322,11 +2325,15 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo // direzione finale precedente const ICurve* pCrvP = pCompo->GetCurve( i - 1) ; Vector3d vtEnd ; pCrvP->GetEndDir( vtEnd) ; + double dLenP ; pCrvP->GetLength( dLenP) ; // direzione iniziale corrente Vector3d vtStart ; pCrvC->GetStartDir( vtStart) ; // angolo tra le direzioni - double dAng ; + double dAng = 0 ; vtEnd.GetAngleXY( vtStart, dAng) ; + // se tratto sotto la tolleranza, ignoro la gestione dell'angolo + if ( dLen < LEN_TOL || dLenP < LEN_TOL) + dAng = 0 ; // Se angolo esterno e richiesto anello esterno if ( IsExternalAngle( dAng) && m_Params.m_nExtCornerType == WJET_EC_LOOP) { // lunghezza tratti lineari @@ -2393,7 +2400,9 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo // ciclo sui punti di accelerazione for ( int j = 1 ; j <= ACC_PNT_NUM ; ++ j) { double dCoeff = j / double( ACC_PNT_NUM) ; - double dU ; pCrvC->GetParamAtLength( dCoeff * dAccLen, dU) ; + double dU = dUprev ; pCrvC->GetParamAtLength( dCoeff * dAccLen, dU) ; + if ( abs( dU - dUprev) < EPS_SMALL) + continue ; PtrOwner pCrvT( pCrvC->Clone()) ; if ( IsNull( pCrvT) || ! pCrvT->TrimStartEndAtParam( dUprev, dU)) return false ; @@ -2456,10 +2465,10 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo // ciclo sui punti di accelerazione for ( int j = 1 ; j <= ACC_PNT_NUM ; ++ j) { double dCoeff = j / double( ACC_PNT_NUM) ; - double dU ; pCrvC->GetParamAtLength( dCoeff * dAccLen, dU) ; - PtrOwner pCrvT( pCrvC->Clone()) ; + double dU = dUprev ; pCrvC->GetParamAtLength( dCoeff * dAccLen, dU) ; if ( abs( dUprev - dU) < EPS_SMALL) continue ; + PtrOwner pCrvT( pCrvC->Clone()) ; if ( IsNull( pCrvT) || ! pCrvT->TrimStartEndAtParam( dUprev, dU)) return false ; Vector3d vtTool = ( 1 - dCoeff) * vtTp + dCoeff * vtTn ; @@ -2485,8 +2494,13 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo // direzione iniziale successiva const ICurve* pCrvN = pCompo->GetCurve( i + 1) ; Vector3d vtStart ; pCrvN->GetStartDir( vtStart) ; + double dLenN ; pCrvN->GetLength( dLenN) ; // angolo tra le direzioni - double dAng ; vtEnd.GetAngleXY( vtStart, dAng) ; + double dAng = 0 ; + vtEnd.GetAngleXY( vtStart, dAng) ; + // se tratto sotto la tolleranza, ignoro la gestione dell'angolo + if ( dLen < LEN_TOL || dLenN < LEN_TOL) + dAng = 0 ; // se angolo esterno e richiesto rallentamento esterno, aggiungo decelerazione if ( IsExternalAngle( dAng) && m_Params.m_nExtCornerType == WJET_EC_SLOW) { // lunghezza entità @@ -2498,7 +2512,7 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo // ciclo sui punti di decelerazione for ( int j = 0 ; j < ACC_PNT_NUM ; ++ j) { double dCoeff = j / double( ACC_PNT_NUM) ; - double dU ; pCrvC->GetParamAtLength( dLen - ( 1 - dCoeff) * dAccLen, dU) ; + double dU = dUprev ; pCrvC->GetParamAtLength( dLen - ( 1 - dCoeff) * dAccLen, dU) ; if ( abs( dUprev - dU) < EPS_SMALL) continue ; PtrOwner pCrvT( pCrvC->Clone()) ; @@ -2524,31 +2538,31 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo // se prima entità e modalità WJET_IC_SLOW_FULL verifico se davvero applicabile controllando angolo con ultima entità if ( i == 0 && m_Params.m_nIntCornerType == WJET_IC_SLOW_FULL) { - bSlowFull = true ; - if ( bClosed) { - // creo una copia della curva senza l'overlap aggiunto - PtrOwner pCrvTmp( pCompo->Clone()) ; - double dLen ; pCrvTmp->GetLength( dLen) ; - if ( IsNull( pCrvTmp) || ! pCrvTmp->TrimEndAtLen( dLen - dAddedOverlap)) - return false ; - // verifico che anche angolo sullo start della curva sia di tipo prev - const ICurve* pCrvLast = pCrvTmp->GetLastCurve() ; - Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; - Vector3d vtEnd ; pCrvLast->GetEndDir( vtEnd) ; - if ( AreSameVectorApprox( vtStart, vtEnd)) { - // se curve in tangenza controllo angolo tra l'ultima e la penultima curva - int nCrvNbr = pCrvTmp->GetCurveCount() ; - const ICurve* pCrvP = pCrvTmp->GetCurve( nCrvNbr - 2) ; - pCrvLast->GetStartDir( vtStart) ; - pCrvP->GetEndDir( vtEnd) ; - } - // se angolo precedente non è interno il tratto non va realizzato in modalità full - double dAngPrev ; vtEnd.GetAngleXY( vtStart, dAngPrev) ; - if ( ! IsInternalAngle( dAngPrev)) - bSlowFull = false ; - } - // salvo il valore per l'ultima entità - bStartSlowFull = bSlowFull ; + bSlowFull = true ; + if ( bClosed) { + // creo una copia della curva senza l'overlap aggiunto + PtrOwner pCrvTmp( pCompo->Clone()) ; + double dLen ; pCrvTmp->GetLength( dLen) ; + if ( IsNull( pCrvTmp) || ! pCrvTmp->TrimEndAtLen( dLen - dAddedOverlap)) + return false ; + // verifico che anche angolo sullo start della curva sia di tipo prev + const ICurve* pCrvLast = pCrvTmp->GetLastCurve() ; + Vector3d vtStart ; pCurve->GetStartDir( vtStart) ; + Vector3d vtEnd ; pCrvLast->GetEndDir( vtEnd) ; + if ( AreSameVectorApprox( vtStart, vtEnd)) { + // se curve in tangenza controllo angolo tra l'ultima e la penultima curva + int nCrvNbr = pCrvTmp->GetCurveCount() ; + const ICurve* pCrvP = pCrvTmp->GetCurve( nCrvNbr - 2) ; + pCrvLast->GetStartDir( vtStart) ; + pCrvP->GetEndDir( vtEnd) ; + } + // se angolo precedente non è interno il tratto non va realizzato in modalità full + double dAngPrev ; vtEnd.GetAngleXY( vtStart, dAngPrev) ; + if ( ! IsInternalAngle( dAngPrev)) + bSlowFull = false ; + } + // salvo il valore per l'ultima entità + bStartSlowFull = bSlowFull ; } if ( bSlowFull) @@ -2577,7 +2591,7 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo // ciclo sui punti di decelerazione for ( int j = 0 ; j < ACC_PNT_NUM ; ++ j) { double dCoeff = j / double( ACC_PNT_NUM) ; - double dU ; pCrvC->GetParamAtLength( dLen - ( 1 - dCoeff) * dAccLen, dU) ; + double dU = dUprev ; pCrvC->GetParamAtLength( dLen - ( 1 - dCoeff) * dAccLen, dU) ; if ( abs( dUprev - dU) < EPS_SMALL) continue ; PtrOwner pCrvT( pCrvC->Clone()) ; @@ -3037,11 +3051,17 @@ WaterJetting::CalcOffset( ICurveComposite* pCompo, double dSignOffs) if ( OffsCrv.Make( pCompo, dSignOffs, nFlag)) { ICurve* pOffs = OffsCrv.GetLongerCurve() ; if ( pOffs != nullptr) { + Point3d ptStart ; pCompo->GetStartPoint( ptStart) ; Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ; pCompo->Clear() ; pCompo->AddCurve( pOffs) ; // ripristino estrusione della curva compo ( rimossa dal Clear) pCompo->SetExtrusion( vtExtr) ; + // ripristino punto iniziale + double dPar ; + int nFlagDist ; + if ( DistPointCurve( ptStart, *pCompo).GetParamAtMinDistPoint( 0, dPar, nFlagDist)) + pCompo->ChangeStartPoint( dPar) ; bOk = true ; } }