diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 848be9f..7a2338a 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -398,6 +398,102 @@ AssignFeedForOpenEdge( ICurveComposite* pCrv, const ICurveComposite* pCrvOF_orig return true ; } +//---------------------------------------------------------------------------- +static bool +SimplifyCurveByFeeds( ICurveComposite* pCrvCompo, const PocketParams& PockParam, double dToler) +{ + // controllo la validità della curva + if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0) + return false ; + + // NB. Effettuo il Merge dei tratti di curva che presentano la stessa Feed ( mediante la tolleranza) + + // curva semplificata + PtrOwner pCrvSimple( CreateCurveComposite()) ; + if ( IsNull( pCrvSimple)) + return false ; + + /* + - effettuo il Merge dei tratti di curva che presentano la stessa Feed + - imposto la Feed dei tratti piccoli come quella dei tratti precedenti ( per evitare singolarità) + - effettuo un nuovo Merge per uniformare ulteriormente i nuovi tratti ottenuti + */ + double dCurrTempParam ; + int nParStart = 0 ; + double dTempParam ; + double dLen ; + for ( int i = 0 ; i < pCrvCompo->GetCurveCount() ; ++ i) { + pCrvCompo->GetCurveTempParam( i, dTempParam) ; + if ( i == 0) { + dCurrTempParam = dTempParam ; + nParStart = i ; + } + else if ( abs( dCurrTempParam - dTempParam) > dToler) { // se parametri diversi + // recupero il tratto di curva uniforme + PtrOwner pCrv( ConvertCurveToComposite( pCrvCompo->CopyParamRange( nParStart, i))) ; + if ( IsNull( pCrv)) + return false ; + // 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->GetLength( dLen) ; + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) + pCrv->SetCurveTempParam( u, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; + pCrvSimple->AddCurve( Release( pCrv)) ; + dCurrTempParam = dTempParam ; + nParStart = i ; + } + } + // 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) ; + double dLen ; pCrvLast->GetLength( dLen) ; + for ( int u = 0 ; u < pCrvLast->GetCurveCount() ; ++ u) + pCrvLast->SetCurveTempParam( u, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; + pCrvSimple->AddCurve( Release( pCrvLast)) ; + } + + // pulisco la curva originale + pCrvCompo->Clear() ; + + // scorro i nuovi tratti ottenuti e ripeto il ragionamento + for ( int i = 0 ; i < pCrvSimple->GetCurveCount() ; ++ i) { + pCrvSimple->GetCurveTempParam( i, dTempParam) ; + if ( i == 0) { + dCurrTempParam = dTempParam ; + nParStart = i ; + } + else if ( abs( dCurrTempParam - dTempParam) > dToler) { + PtrOwner pCrv( ConvertCurveToComposite( pCrvSimple->CopyParamRange( nParStart, i))) ; + if ( IsNull( pCrv)) + return false ; + pCrv->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL, false) ; + // recupero la lunghezza di tale curve + double dLen ; pCrv->GetLength( dLen) ; + for ( int u = 0 ; u < pCrv->GetCurveCount() ; ++ u) + pCrv->SetCurveTempParam( u, ( 0.1 * PockParam.dRad < dLen ? dCurrTempParam : dTempParam), 0) ; + pCrvCompo->AddCurve( Release( pCrv)) ; // aggiungo alla curva finale + dCurrTempParam = dTempParam ; + nParStart = i ; + } + } + // ultima parte di curva uniforme ... + pCrvLast.Set( ConvertCurveToComposite( pCrvSimple->CopyParamRange( nParStart, pCrvSimple->GetCurveCount()))) ; + if ( ! IsNull( pCrvLast)) { + // semplifico + pCrvLast->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL, 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) ; + pCrvCompo->AddCurve( Release( pCrvLast)) ; + } + + return true ; +} + //---------------------------------------------------------------------------- static bool AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved_offs, bool bIsLink, @@ -431,7 +527,7 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved_offs // restringo la superificie in maniera appropriata if ( bIsLink) { // se curva di Link - if ( ! pSrf_Removed_offs_clone->Offset( - PockParams.dRad + 1500 * EPS_SMALL, ICurve::OFF_CHAMFER) || + if ( ! pSrf_Removed_offs_clone->Offset( - PockParams.dRad, ICurve::OFF_CHAMFER) || ! pSrf_Removed_offs_clone->IsValid() || pSrf_Removed_offs_clone->GetChunkCount() == 0) return true ; // esco ( sempre con Feed Minima) } @@ -454,17 +550,17 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved_offs for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) { // recupero il tratto di curva ricavato dalla classificazione double dCurrFeed = GetMinFeed( PockParams) ; - PtrOwner PCrv_sez( ConvertCurveToComposite( pCrv->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ; - if ( IsNull( PCrv_sez)) + PtrOwner pCrv_sez( ConvertCurveToComposite( pCrv->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE))) ; + if ( IsNull( pCrv_sez)) continue ; // curva troppo piccola, passo alla successiva // controllo se interno o fuori alla regione ( regolando quindi la Feed) if ( ccClass[i].nClass == CRVC_IN) // se interna alla regione rimossa... dCurrFeed = GetMaxFeed( PockParams) ; // assegno tale Feed ad ogni sottocurva ricavata dal tratto di classificazione - for ( int u = 0 ; u < PCrv_sez->GetCurveCount() ; ++ u) - PCrv_sez->SetCurveTempParam( u, dCurrFeed, 0) ; + for ( int u = 0 ; u < pCrv_sez->GetCurveCount() ; ++ u) + pCrv_sez->SetCurveTempParam( u, dCurrFeed, 0) ; // aggiungo la nuova curva con la Feed regolata a quella finale - pCrv_new->AddCurve( Release( PCrv_sez)) ; + pCrv_new->AddCurve( Release( pCrv_sez)) ; } // sotituisco con quanto calcolato @@ -1755,7 +1851,7 @@ GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParam if ( IsNull( pSfrToOffset)) return false ; if ( bExtAllClose) // se il loop esterno è chiuso, lo aggiungo - pSfrToOffset->AddExtLoop( pCrvExtLoop->Clone()) ; //AAAAAAAAAAAAAAA + pSfrToOffset->AddExtLoop( Release( pCrvExtLoop)) ; // se ho delle isole e il loop esterno è uniforme ( tutto aperto o chiuso) if ( bHasIslands && ( bExtAllClose || bExtAllOpen)) { @@ -1833,12 +1929,23 @@ GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParam if ( vCrvCompoRes_tmp.empty()) return true ; + // recupero la superficie limite ( se esiste ed è valida) + PtrOwner pSfrLimit( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrLimit)) + return false ; + // per tutte le curve inserite, devo tenere solamente quelle esterne alla superficie limite if ( PockParams.SfrLimit.IsValid()) { // se esiste, allora classifico + // recupero la superficie limite + pSfrLimit.Set( PockParams.SfrLimit.Clone()) ; + if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid()) + return false ; + // effettuo un Offset della regione, tutto ciò che dista più del raggio utensile non la rovina + pSfrLimit->Offset( PockParams.dRad - 250 * EPS_SMALL, ICurve::OFF_FILLET) ; // c'è un offset radiale, quindi tengo tolleranza alta ICRVCOMPOPOVECTOR vCrvCompoRes_tmp_Splitted ; for ( int i = 0 ; i < int( vCrvCompoRes_tmp.size()) ; ++ i) { CRVCVECTOR ccClass ; - if ( PockParams.SfrLimit.GetCurveClassification( *vCrvCompoRes_tmp[i], EPS_SMALL, ccClass)) { + if ( pSfrLimit->GetCurveClassification( *vCrvCompoRes_tmp[i], EPS_SMALL, ccClass)) { for ( int j = 0 ; j < int( ccClass.size()) ; ++ j) { if ( ccClass[j].nClass == CRVC_OUT) { PtrOwner pCrvRes( ConvertCurveToComposite( vCrvCompoRes_tmp[i]->CopyParamRange( ccClass[j].dParS, ccClass[j].dParE))) ; @@ -1869,27 +1976,29 @@ GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParam // recupero il punto di caduta dell'utensile Point3d ptFall = ptStart - vtStart * ( PockParams.dRad + PockParams.dOpenMinSafe) ; // controllo che il tool non sia interno alla regione limite - PtrOwner pCrvToolShape( CreateCurveArc()) ; - if ( IsNull( pCrvToolShape) || ! pCrvToolShape->Set( ptFall, Z_AX, PockParams.dRad - 100 * EPS_SMALL)) - return false ; - CRVCVECTOR ccClass ; - if ( PockParams.SfrLimit.GetCurveClassification( *pCrvToolShape, EPS_SMALL, ccClass) && - int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) { - vCrvCompoRes_tmp[i]->AddLine( ptFall, false) ; - vCrvCompoRes_tmp[i]->SetCurveTempProp( 0, TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out - vCrvCompoRes_tmp[i]->SetCurveTempParam( 0, GetMinFeed( PockParams) , 0) ; // Feed minima - } - else { // se trovo intersezione, provo a ruotare di 90° - vtStart.Rotate( Z_AX, ANG_RIGHT) ; // verso sinistra - ptFall = ptStart + vtStart * ( PockParams.dRad + PockParams.dOpenMinSafe) ; - if ( ! pCrvToolShape->Set( ptFall, Z_AX, PockParams.dRad - 100 * EPS_SMALL)) + if ( pSfrLimit->IsValid()) { + PtrOwner pCrvToolShape( CreateCurveArc()) ; + if ( IsNull( pCrvToolShape) || ! pCrvToolShape->Set( ptFall, Z_AX, PockParams.dRad - 100 * EPS_SMALL)) return false ; - ccClass.clear() ; - if ( PockParams.SfrLimit.GetCurveClassification( *pCrvToolShape, EPS_SMALL, ccClass) && + CRVCVECTOR ccClass ; + if ( pSfrLimit->GetCurveClassification( *pCrvToolShape, EPS_SMALL, ccClass) && int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) { vCrvCompoRes_tmp[i]->AddLine( ptFall, false) ; vCrvCompoRes_tmp[i]->SetCurveTempProp( 0, TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out - vCrvCompoRes_tmp[i]->SetCurveTempParam( 0, GetMinFeed( PockParams) , 0) ; // Feed massima + vCrvCompoRes_tmp[i]->SetCurveTempParam( 0, GetMinFeed( PockParams) , 0) ; // Feed minima + } + else { // se trovo intersezione, provo a ruotare di 90° + vtStart.Rotate( Z_AX, ANG_RIGHT) ; // verso sinistra + ptFall = ptStart + vtStart * ( PockParams.dRad + PockParams.dOpenMinSafe) ; + if ( ! pCrvToolShape->Set( ptFall, Z_AX, PockParams.dRad - 100 * EPS_SMALL)) + return false ; + ccClass.clear() ; + if ( pSfrLimit->GetCurveClassification( *pCrvToolShape, EPS_SMALL, ccClass) && + int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) { + vCrvCompoRes_tmp[i]->AddLine( ptFall, false) ; + vCrvCompoRes_tmp[i]->SetCurveTempProp( 0, TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out + vCrvCompoRes_tmp[i]->SetCurveTempParam( 0, GetMinFeed( PockParams) , 0) ; // Feed massima + } } } // imposto il flag di curva singola @@ -5236,6 +5345,9 @@ GetNewCurvetWithCentroid( const ICurveComposite* pCrvH1, const ICurveComposite* if ( ! AreSameVectorApprox( vtS_cir, vtS_CrvH1)) pPath1->Invert() ; + // assegno la Feed + AssignMinFeed( pPath1, PockParams) ; + // controllo che la circonferenza sia ammissibile ( solo che non esca dalle prime curve di Offset) Point3d ptCrvS ; pPath1->GetStartPoint( ptCrvS) ; if ( ! CutCurveByOffsets( pPath1, VFirstOff)) // taglio la curva sugli Offsets @@ -5278,6 +5390,10 @@ GetNewCurvetWithCentroid( const ICurveComposite* pCrvH1, const ICurveComposite* ! CalcBoundedSmoothedLink( ptE, vtTanS, ptS, vtTanS, 0.5, VFirstOff, PockParams, pPath2)) return false ; + // assegno la Feed a queste due nuove curve + AssignMinFeed( pPath1, PockParams) ; + AssignMinFeed( pPath2, PockParams) ; + // creo la nuova curva con il doppio Biarco if ( pCrvH1 != nullptr && pCrvH1->GetFirstCurve() != nullptr) if ( ! pCrvNewCurve->AddCurve( pCrvH1->Clone())) // aggiungo inizio @@ -5320,7 +5436,7 @@ ManageSmoothAndAutoInters( ICurveComposite* pCrv, ICurveComposite* pCrvPath, ICu CRVCVECTOR ccClass ; IntersCurveCurve intCC( *pLine, *pCrv) ; intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; - if (( int)ccClass.size() > 1) // se intersezione con parte precedente inverto la direzione + if ( int( ccClass.size()) > 1) // se intersezione con parte precedente inverto la direzione pLine->SetPVL( ptHS, - vTanE, ( 2 * PockParams.dRad) / 3 - 5 * EPS_SMALL) ; if ( IsNull( pLine) || ! pLine->IsValid()) @@ -5446,6 +5562,9 @@ GetNewCurvetWithPath( const ICurveComposite* pCrvH1, const ICurveComposite* pCrv if ( ! ManageSmoothAndAutoInters( pCrvToAdd, pCrvPath, pPath1, PockParams, pPath2, VoffsCl)) return false ; + // imposto la Feed + AssignMinFeed( pCrvToAdd, PockParams) ; + // curva finale if ( pCrvH1 != nullptr && pCrvH1->GetFirstCurve() != nullptr) if ( ! pCrvNewCurve->AddCurve( pCrvH1->Clone())) // aggiungo inizio @@ -5464,6 +5583,9 @@ GetNewCurvetWithPath( const ICurveComposite* pCrvH1, const ICurveComposite* pCrv if ( ! CalcBoundedLink( ptHS, ptHE, VFirstOff, pCrvBiArcHelper)) return false ; + // assegno la Feed + AssignMinFeed( pCrvBiArcHelper, PockParams) ; + if ( ! pCrvNewCurve->AddCurve( Release( pCrvBiArcHelper)) || ! pCrvNewCurve->AddCurve( pCrvToAdd->Clone())) return false ; @@ -5484,6 +5606,9 @@ GetNewCurvetWithPath( const ICurveComposite* pCrvH1, const ICurveComposite* pCrv if ( ! CalcBoundedLink( ptHS, ptHE, VFirstOff, pCrvBiArcHelper) ) return false ; + // assegno la Feed + AssignMinFeed( pCrvBiArcHelper, PockParams) ; + if ( ! pCrvNewCurve->AddCurve( pCrvBiArcHelper->Clone()) || ! pCrvNewCurve->AddCurve( pCrvH2->Clone())) { ++nTry ; @@ -6163,7 +6288,6 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int if ( vOffs.empty()) return true ; - // cambio il punto iniziale della prima Curva di Offset Point3d ptRef = PockParams.ptEnd ; ptRef.ToLoc( frPocket) ; Point3d ptNewStart ; @@ -6238,6 +6362,9 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int pMCrv->AddCurve( vOffs[i]->Clone()) ; } + // semplifico la curva ottenuta + SimplifyCurveByFeeds( pMCrv, PockParams, 10 * EPS_SMALL) ; + // verifico il percorso di lavoro if ( pMCrv->GetCurveCount() == 0) return false ; diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index ee6245e..20e3680 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -5090,7 +5090,7 @@ VolZmap::CompPar_Milling( int nGrid, double dLenX, double dLenY, double dLenZ, // ---------- SFERA ---------------------------------------------------------- -//---------------------------------------------------------------------------- pizza +//---------------------------------------------------------------------------- bool VolZmap::CompBall_Milling( int nGrid, const Point3d& ptLs, const Point3d& ptLe, double dRad, int nToolNum) {