diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index e47de23..06a61b8 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -512,10 +512,10 @@ SimplifyCurveByFeeds( ICurveComposite* pCrvCompo, const PocketParams& PockParam, // lo semplifico // recupero la lunghezza del tratto e imposto associo la Feed corrente // se curva corta -> il parametro di Feed è definito da quello precedente - pCrv->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL, false) ; + pCrv->MergeCurves( 100 * EPS_SMALL, ANG_TOL_STD_DEG, false) ; pCrv->GetLength( dLen) ; - for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) - pCrv->SetCurveTempParam( u, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; + for ( int nU = 0 ; nU < pCrv->GetCurveCount() ; ++ nU) + pCrv->SetCurveTempParam( nU, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; pCrvSimple->AddCurve( Release( pCrv)) ; dCurrTempParam = dTempParam ; nParStart = i ; @@ -524,10 +524,10 @@ SimplifyCurveByFeeds( ICurveComposite* pCrvCompo, const PocketParams& PockParam, // ultima parte di curva uniforme ... PtrOwner pCrvLast( ConvertCurveToComposite( pCrvCompo->CopyParamRange( nParStart, pCrvCompo->GetCurveCount()))) ; if ( ! IsNull( pCrvLast)) { - pCrvLast->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL, false) ; + pCrvLast->MergeCurves( 100 * EPS_SMALL, ANG_TOL_STD_DEG, false) ; double dLen ; pCrvLast->GetLength( dLen) ; - for ( int u = 0 ; u < pCrvLast->GetCurveCount() ; ++ u) - pCrvLast->SetCurveTempParam( u, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; + for ( int nU = 0 ; nU < pCrvLast->GetCurveCount() ; ++ nU) + pCrvLast->SetCurveTempParam( nU, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; pCrvSimple->AddCurve( Release( pCrvLast)) ; } @@ -545,7 +545,7 @@ SimplifyCurveByFeeds( ICurveComposite* pCrvCompo, const PocketParams& PockParam, PtrOwner pCrv( ConvertCurveToComposite( pCrvSimple->CopyParamRange( nParStart, i))) ; if ( IsNull( pCrv)) return false ; - pCrv->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL, false) ; + pCrv->MergeCurves( 100 * EPS_SMALL, ANG_TOL_STD_DEG, false) ; // recupero la lunghezza di tale curve double dLen ; pCrv->GetLength( dLen) ; for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) @@ -559,11 +559,11 @@ SimplifyCurveByFeeds( ICurveComposite* pCrvCompo, const PocketParams& PockParam, pCrvLast.Set( ConvertCurveToComposite( pCrvSimple->CopyParamRange( nParStart, pCrvSimple->GetCurveCount()))) ; if ( ! IsNull( pCrvLast)) { // semplifico - pCrvLast->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL, false) ; + pCrvLast->MergeCurves( 100 * EPS_SMALL, ANG_TOL_STD_DEG, false) ; // recupero la lunghezza di tale curva e imposto la Feed pCrvLast->GetLength( dLen) ; - for ( int u = 0 ; u < pCrvLast->GetCurveCount() ; ++ u) - pCrvLast->SetCurveTempParam( u, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; + for ( int nU = 0 ; nU < pCrvLast->GetCurveCount() ; ++ nU) + pCrvLast->SetCurveTempParam( nU, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; pCrvCompo->AddCurve( Release( pCrvLast)) ; } @@ -4816,12 +4816,13 @@ CalcBoundedSmoothedLink( const Point3d& ptStart, const Vector3d& vtStart, const if ( SqDist( ptStart, ptEnd) > dSqTol) bSpecial = ( CalcSpecialBoundedSmoothedLink( ptStart, vtStart, ptEnd, vtEnd, PockParams, pMyCrvLink)) ; if ( ! pMyCrvLink->IsValid() || pMyCrvLink->GetCurveCount() == 0) { - // ...in caso negativo creo il Biarco ( se parametro a zero, allora circonferenza) + // ...in caso negativo creo il Biarco double dAngStart ; vtStart.GetAngleXY( X_AX, dAngStart) ; double dAngEnd ; vtEnd.GetAngleXY( X_AX, dAngEnd) ; if ( dParMeet > EPS_ZERO) pMyCrvLink.Set( ConvertCurveToComposite( GetBiArc( ptStart, -dAngStart, ptEnd, -dAngEnd, dParMeet))) ; else { + // ... o una circonferenza, orientata in modo da poter essere classificata con le curve di bordo PtrOwner pCrvCir( CreateBasicCurveArc()) ; if ( IsNull( pCrvCir)) return false ; @@ -4908,6 +4909,15 @@ CalcBoundedSmoothedLink( const Point3d& ptStart, const Vector3d& vtStart, const } // La curva necessita di un ulteriore smusso, in quanto tagliata su un bordo ModifyCurveToSmoothed( pCompoTest, PockParams, PockParams.dRad / 4., PockParams.dRad / 4., false) ; + // nel caso speciale della circonferenza, devo impostare il punto iniziale + if ( dParMeet < EPS_ZERO) { + if ( pCompoTest->IsClosed()) { // sempre... + double dU = 0. ; + int nFlag = 0 ; + if ( DistPointCurve( ptStart, *pCompoTest).GetParamAtMinDistPoint( 0., dU, nFlag)) + pCompoTest->ChangeStartPoint( dU) ; + } + } // restituisco il Link if ( IsNull( pCompoTest) || ! pCompoTest->IsValid() || pCompoTest->GetCurveCount() == 0) @@ -5384,7 +5394,7 @@ RemoveUnclearedRegions( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& bool bSpecial = false ; // se parallele, allora trasformo in una circonferenza if ( bSameDir) { - if ( ! CalcBoundedSmoothedLink( ptMain, V_INVALID, ptCentroid, V_INVALID, 0., vOffsFirstCurve, PockParams, pCrvCurl, bSpecial)) + if ( ! CalcBoundedSmoothedLink( ptMain, vt1, ptCentroid, vt2, 0., vOffsFirstCurve, PockParams, pCrvCurl, bSpecial)) continue ; Vector3d vtStartCheck ; pCrvCurl->GetStartDir( vtStartCheck) ; if ( AreOppositeVectorApprox( vtStartCheck, vt1)) @@ -5520,21 +5530,21 @@ RemoveUnclearedRegions( const ISurfFlatRegion* pSfrUncleared, ICRVCOMPOPOVECTOR& if ( IsNull( pCrvTest)) return false ; // aggiungo tratto iniziale di Offset - pCrvTest->AddCurve( ConvertCurveToBasicComposite( pMyOffs->CopyParamRange( 0, dURef1))) ; + pCrvTest->AddCurve( ConvertCurveToComposite( pMyOffs->CopyParamRange( 0, dURef1))) ; // aggiungo la curva a ricciolo if ( ! pCrvTest->AddCurve( Release( pCrvCurl))) continue ; // aggiungo il tratto finale di Offset - pCrvTest->AddCurve( ConvertCurveToBasicComposite( pMyOffs->CopyParamRange( dURef2, pMyOffs->GetCurveCount()))) ; + pCrvTest->AddCurve( ConvertCurveToComposite( pMyOffs->CopyParamRange( dURef2, pMyOffs->GetCurveCount()))) ; // provo a controllare che i punti inziali e finali coincidano, in caso aggiorno il nuovo Offset Point3d ptStart_Old ; vOffs[nInd]->GetStartPoint( ptStart_Old) ; Point3d ptEnd_Old ; vOffs[nInd]->GetEndPoint( ptEnd_Old) ; Point3d ptStart_New ; pCrvTest->GetStartPoint( ptStart_New) ; Point3d ptEnd_New ; pCrvTest->GetEndPoint( ptEnd_New) ; if ( AreSamePointApprox( ptStart_Old, ptStart_New) && AreSamePointApprox( ptEnd_Old, ptEnd_New)) { - pCrvTest->SetTempProp( vOffs[nInd]->GetTempProp( 0), 0) ; - pCrvTest->SetTempProp( vOffs[nInd]->GetTempProp( 1), 1) ; - vOffs[nInd].Set( pCrvTest) ; + pCrvTest->SetTempProp( vOffs[nInd]->GetTempProp( 0), 0) ; + pCrvTest->SetTempProp( vOffs[nInd]->GetTempProp( 1), 1) ; + vOffs[nInd].Set( pCrvTest) ; } } @@ -5722,10 +5732,6 @@ CheckIfOffsetIsNecessary( const ISurfFlatRegion* pSfrAct, const ICurveComposite* } // controllo se l'Offset rimuove una quantità minima di materiale else if ( dMaxOffs + ( dOffs - dOffsPrec) - PockParams.dRad < TOL_REMOVE_OFFSET) { - // evito questo passaggio se sono alla seconda iterazione, potrei creare regioni - // non svuotate raggiungibili mediante raccordi a circonferenza allacciati a tratti chiusi - if ( nIter == 1) - return true ; // inizializzo la curva di bordo della regione non svuotata PtrOwner pCrvBorder( CreateCurveComposite()) ; if ( IsNull( pCrvBorder)) diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 6e3e776..6943ea0 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -3169,11 +3169,26 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn // se precedente molto corta double dLenP ; if ( pCrvP->GetLength( dLenP) && dLenP < dCurrLinTol) { - // se abbastanza allineata alla successiva + // se abbastanza allineata alla successiva Vector3d vtDirP, vtDirC ; if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) { - Point3d ptStart ; - return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ; + bool bModifStart = ( pCrvC->GetType() != CRV_ARC) ; + if ( ! bModifStart) { + /* nel caso in cui la curva corrente sia un arco, bisogna controllare che la somma tra + l'angolo al centro e l'angolo sotteso dalla curva precedente non superi l'angolo giro; in + caso positivo, la modifica del punto inziale dell'arco ( curva corrente) rimoverebbe + tutti gli angoli superiori a 360deg [curve a ricciolo per regioni non svuotate in Pocketing] */ + Point3d ptS ; pCrvP->GetStartPoint( ptS) ; + Point3d ptE ; pCrvC->GetStartPoint( ptE) ; + const ICurveArc* pArcC = GetBasicCurveArc( pCrvC) ; + double dAngRef = ( Dist( ptS, ptE) / pArcC->GetRadius()) * RADTODEG ; + bModifStart = ( abs( pArcC->GetAngCenter()) + dAngRef < ANG_FULL - 10 * EPS_ANG_SMALL) ; + + } + if ( bModifStart) { + Point3d ptStart ; + return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ; + } } } // se corrente molto corta @@ -3182,10 +3197,24 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn // se abbastanza allineata alla precedente Vector3d vtDirP, vtDirC ; if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) { - Point3d ptEnd ; - return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ; + bool bModifEnd = ( pCrvP->GetType() != CRV_ARC) ; + if ( ! bModifEnd) { + /* nel caso in cui la curva predecente sia un arco, bisogna controllare che la somma tra + l'angolo al centro e l'angolo sotteso dalla curva corrente non superi l'angolo giro; in + caso positivo, la modifica del punto finale dell'arco ( curva precedente) rimoverebbe + tutti gli angoli superiori a 360deg [curve a ricciolo per regioni non svuotate in Pocketing] */ + Point3d ptS ; pCrvP->GetEndPoint( ptS) ; + Point3d ptE ; pCrvC->GetEndPoint( ptE) ; + const CurveArc* pArcP = GetBasicCurveArc( pCrvP) ; + double dAngRef = ( Dist( ptS, ptE) / pArcP->GetRadius()) * RADTODEG ; + bModifEnd = ( abs( pArcP->GetAngCenter()) + dAngRef < ANG_FULL - 10. * EPS_ANG_SMALL) ; + } + if ( bModifEnd) { + Point3d ptEnd ; + return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ; + } } - } + } // coefficiente deduzione tolleranza const double COEFF_TOL = 0.7 ; // se entrambe rette