From a7be952e117c9462945a43df77143e108b84258c Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Fri, 12 Jul 2024 13:49:20 +0200 Subject: [PATCH 1/5] EgtGeomKernel : - in Pocketing, alla fine di CalcSpiral aggiunto reset dei TempProp delle curve componenti i percorsi risultanti. --- CalcPocketing.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 75fcebb..9ccc041 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -6252,6 +6252,12 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int if ( pMCrv->GetCurveCount() == 0) return false ; + // reset delle proprietà temporanee delle curve componenti + for ( int i = 0 ; i < pMCrv->GetCurveCount() ; ++ i) { + pMCrv->SetCurveTempProp( i, 0, 0) ; + pMCrv->SetCurveTempProp( i, 0, 1) ; + } + // setto estrusione pMCrv->SetExtrusion( vtExtr) ; From 95ff8b21b94bdab0a663017eaedc6850e8a1cb17 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Fri, 12 Jul 2024 16:29:53 +0200 Subject: [PATCH 2/5] EgtGeomKernel : - In CalcPocketing aggiunta funzione per Chain delle curve singole di svuotatura - Inversione dei percorsi per lavorazione utensile - Migliorati i controlli per le entrate da fuori. --- CalcPocketing.cpp | 369 +++++++++++++++++++++++++++++----------------- 1 file changed, 230 insertions(+), 139 deletions(-) diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 9ccc041..238df29 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -31,6 +31,7 @@ #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EgtNumUtils.h" +#include "/EgtDev/Include/EGkChainCurves.h" #include using namespace std ; @@ -1698,6 +1699,169 @@ CheckForRemovingIsland( const ICurveComposite* pCrvIslandBorder, double dOffs, b return true ; } +//---------------------------------------------------------------------------- +static bool +ChainCompoCurves( ICRVCOMPOPOVECTOR& vCrvCompo) +{ + /* concatenamento delle curve composite */ + if ( int( vCrvCompo.size() < 2)) + return true ; + + // controllo validità delle curve + for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) + if ( IsNull( vCrvCompo[i]) || ! vCrvCompo[i]->IsValid()) + return false ; + + // preparo i dati per il concatenamento + bool bFirst = true ; + Point3d ptNear = ORIG ; + double dToler = 500 * EPS_SMALL ; // leggermente maggiore della tolleranza sulla superficie limite + ChainCurves chainC ; + chainC.Init( false, dToler, int( vCrvCompo.size())) ; + for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) { + // recupero i dati della curva necessari al concatenamento e li assegno + Point3d ptStart, ptEnd ; + Vector3d vtStart, vtEnd ; + if ( ! vCrvCompo[i]->GetStartPoint( ptStart) || ! vCrvCompo[i]->GetStartDir( vtStart) || + ! vCrvCompo[i]->GetEndPoint( ptEnd) || ! vCrvCompo[i]->GetEndDir( vtEnd)) + return false ; + if ( ! chainC.AddCurve( int( i + 1), ptStart, vtStart, ptEnd, vtEnd)) + return false ; + // se prima curva, assegno inizio della ricerca + if ( bFirst) { + ptNear = ptStart + 10 * EPS_SMALL * vtStart ; + bFirst = false ; + } + } + + // vettore delle curve composite risultante + ICRVCOMPOPOVECTOR vCrvCompoChained ; + + // recupero i percorsi concatenati + INTVECTOR vnInd ; + while ( chainC.GetChainFromNear( ptNear, true, vnInd)) { + // creo una curva composita + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo)) + return false ; + // recupero le curve semplici e le inserisco nella curva composita + for ( size_t i = 0 ; i < vnInd.size() ; ++ i) { + int nId = abs( vnInd[i]) - 1 ; + bool bInvert = ( vnInd[i] < 0) ; + // se necessario, la inverto + if ( bInvert) + vCrvCompo[nId]->Invert() ; + // la aggiungo alla curva composta + if ( ! pCrvCompo->AddCurve( ::Release( vCrvCompo[nId]), true, dToler)) + return false ; + } + // aggiorno il nuovo punto vicino + if ( pCrvCompo->GetCurveCount() > 0) { + pCrvCompo->GetEndPoint( ptNear) ; + vCrvCompoChained.emplace_back( Release( pCrvCompo)) ; + } + } + + swap( vCrvCompoChained, vCrvCompo) ; + return true ; +} + +//---------------------------------------------------------------------------- +static bool +AdjustOpenCurves( ICRVCOMPOPOVECTOR& vCrvCompo, const PocketParams& PockParams) +{ + /* + sistemazione punto di inizio, segmento per LeadIn, e Feed + ( Se la curva è chiusa, allora si può cambiare il punto d'inizio) + */ + + // controllo validità delle curve + for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) + if ( IsNull( vCrvCompo[i]) || ! vCrvCompo[i]->IsValid()) + return false ; + + // recupero la superficie limite ( se esiste ed è valida) + PtrOwner pSfrLimit( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrLimit)) + return false ; + 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 + } + + // per ogni curva signola, aggiungo l'entrata da fuori se ammissibile + for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) { + + int nMaxIter = ( vCrvCompo[i]->IsClosed() ? 4 : 1) ; + double dLen = EPS_SMALL ; + if ( nMaxIter == 4) + vCrvCompo[i]->GetLength( dLen) ; + + if ( PockParams.bInvert) + vCrvCompo[i]->Invert() ; + + for ( int j = 0 ; j < nMaxIter ; ++ j) { + if ( j > 0) + vCrvCompo[i]->ChangeStartPoint( dLen / nMaxIter) ; + + // ricavo punto di inizio e vettore tangente + Point3d ptStart ; vCrvCompo[i]->GetStartPoint( ptStart) ; + Vector3d vtStart ; vCrvCompo[i]->GetStartDir( vtStart) ; + // recupero il punto di caduta dell'utensile + Point3d ptFall = ptStart - vtStart * ( 2 * PockParams.dRad + PockParams.dOpenMinSafe) ; + // controllo che il tool non sia interno alla regione limite + bool bAllowLeadIn = ( ! pSfrLimit->IsValid()) ; + if ( ! bAllowLeadIn) { + // calcolo l'ombra del tool centrata in ptFall + PtrOwner pCrvToolShape( CreateCurveArc()) ; + if ( IsNull( pCrvToolShape) || ! pCrvToolShape->Set( ptFall, Z_AX, PockParams.dRad - 100 * EPS_SMALL)) + return false ; + CRVCVECTOR ccClass ; + bAllowLeadIn = ( pSfrLimit->GetCurveClassification( *pCrvToolShape, EPS_SMALL, ccClass) && + int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) ; + // se esiste intersezione con la limite Offsettata, provo a ruotare di 90° il tratto lineare + if ( ! bAllowLeadIn) { + vtStart.Rotate( Z_AX, PockParams.bInvert ? - ANG_RIGHT : ANG_RIGHT) ; + ptFall = ptStart + vtStart * ( 2 * PockParams.dRad + PockParams.dOpenMinSafe) ; + if ( ! pCrvToolShape->Set( ptFall, Z_AX, PockParams.dRad - 100 * EPS_SMALL)) + return false ; + ccClass.clear() ; + bAllowLeadIn = ( pSfrLimit->GetCurveClassification( *pCrvToolShape, EPS_SMALL, ccClass) && + int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) ; + } + } + if ( bAllowLeadIn) { // se ammessa entrata da fuori + vCrvCompo[i]->AddLine( ptFall, false) ; + vCrvCompo[i]->SetCurveTempProp( 0, TMP_PROP_CRV_OPEN_SIDE, 0) ; // nProp 2 per le curve LeadIn/Out + vCrvCompo[i]->SetCurveTempParam( 0, GetMinFeed( PockParams) , 0) ; // Feed massima + break ; // interrompo a prescindere l'iterazione per i punti iniziali + } + } + } + + // imposto le Feed per tali curve + for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) { + /* + Idea : Feed proporzionale al minimo Offset per annullare la regione + -> Massimo parametro sui bisettori di VORONOI + */ + + // recupero il MaxOffset per la curva + double dMaxOffs = vCrvCompo[i]->GetTempParam( 0) ; + // calcolo la Feed proporzionale a tale Offset + double dFeed ; + GetFeedForParam( 2 * dMaxOffs, PockParams, dFeed) ; + AssignCustomFeed( vCrvCompo[i], PockParams, dFeed) ; + // imposto il flag di curva singola + vCrvCompo[i]->SetTempProp( TMP_PROP_SINGLE_CURVE, 0) ; //nProp per curva singola + } + + return true ; +} //---------------------------------------------------------------------------- static bool GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParams& PockParams, @@ -1754,18 +1918,24 @@ GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParam // Se tutta aperta -> La regione è definita mediante Offset esterno del contorno aperto if ( ( bExtAllClose || bExtAllOpen) && ! bHasIslands) return true ; + // Se il contorno esterno è misto -> non devo avere isole + if ( ! bExtAllClose && ! bExtAllOpen && bHasIslands) + return true ; + // Se il contorno esterno è tutto chiuso e ho più di un'isola non faccio nulla + if ( bExtAllClose && pSfrChunk->GetLoopCount( 0) > 2) + return true ; // scorro i chiusi e sottraggo la regione da loro creata mediante l'utensile // NB. Queste curve sono orientate in maniera corretta - ICRVCOMPOPOVECTOR vCrvOffs ; // salvo il vettore di curve offsettate del raggio utensile + ICRVCOMPOPOVECTOR vCrvCompoRes_tmp ; // salvo il vettore di curve offsettate del raggio utensile for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { if ( vpCrvs[i]->GetTempProp( 0) == 0) { // se tratto chiuso... OffsetCurve OffsCrv ; // con offset verso l'interno - if ( OffsCrv.Make( vpCrvs[i], - PockParams.dRad, ICurve::OFF_FILLET)) { + if ( OffsCrv.Make( vpCrvs[i], - PockParams.dRad - PockParams.dRadialOffset, ICurve::OFF_FILLET)) { PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ; while ( ! IsNull( pOffLongestCrv)) { // salvo la curva corrente - vCrvOffs.emplace_back( ConvertCurveToComposite( Release( pOffLongestCrv))) ; + vCrvCompoRes_tmp.emplace_back( ConvertCurveToComposite( Release( pOffLongestCrv))) ; // passo alla successiva pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ; } @@ -1773,32 +1943,21 @@ GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParam } } - /* + /* Casi gestiti : - 1) La curva esterna è tutta chiusa o tutta aperta e al suo interno ci sono delle isole uniformi - ( quindi ogni isola può essere solo aperta o chiusa) : - - se la curva esterna è tutta aperta, allora la regione da creare è formata da tutte le isole chiuse - e il percorso da seguire sarà un offset verso l'esterno di questa regione - - se la curva esterna è tutta chiusa, allora la regione è definita da questa loop esterno e - come loop interni vengono inserite tutte le isole chiuse; le curva da seguire sono ricavate - da un'offset verso l'interno della regione - 2) La curva esterna non è uniforme, quindi presenta sia tratti chiusi che tratti aperti : - - se non ci sono isole, allora ho già ricavato le curve - - se ci sono isole non faccio nulla ( meglio estendere i lati aperti del loop esterno e - delle isole mediante la funzione AdjustContourWithOpenEdges() - */ + 1) La curva esterna e mista e non ho isole ( ho già il percorso) + 2) La curva esterna è tutta aperta e le isole sono tutte chiuse + 3) La curva esterna è tutta chiusa e ho una sola isola aperta ( ho già il percorso) - // creo la regione finale il cui Offset mi genera le curve di pocketing da seguire ( Offset positivo o negativo) - // NB. Le isole potrebbero unirsi tra di loro mediante gli Offset - PtrOwner pSfrToOffset( CreateSurfFlatRegion()) ; - if ( IsNull( pSfrToOffset)) - return false ; - if ( bExtAllClose) // se il loop esterno è chiuso, lo aggiungo - pSfrToOffset->AddExtLoop( Release( pCrvExtLoop)) ; + */ - // se ho delle isole e il loop esterno è uniforme ( tutto aperto o chiuso) - if ( bHasIslands && ( bExtAllClose || bExtAllOpen)) { - for ( int i = 1 ; i < pSfrChunk->GetLoopCount( 0) ; ++ i) { + // 1) + if ( ! bExtAllClose && ! bExtAllOpen) + ; + else { + // scorro tutte le isole + bool bValidIslands = true ; // flag per isole tutte uniformi + for ( int i = 1 ; i < pSfrChunk->GetLoopCount( 0) && bValidIslands ; ++ i) { // controllo uniformità dell'isola int nCurrTmpProp = -1 ; int nPrecTmpProp = -1 ; @@ -1817,80 +1976,32 @@ GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParam pCrvIsl->SetTempProp( u, 0) ; nCurrTmpProp = 0 ; // aggiorno il Flag } - // se isola chiusa - if ( nCurrTmpProp == 0) { - OffsetCurve OffsCrv ; // con Offset interno ( senso orario) - if ( OffsCrv.Make( pCrvIsl, - PockParams.dRad, ICurve::OFF_FILLET)) { - PtrOwner pOffLongestCrv( OffsCrv.GetLongerCurve()) ; - while ( ! IsNull( pOffLongestCrv)) { - // inverto la curva dato che è il contorno di un'isola - pOffLongestCrv->Invert() ; - // salvo la curva corrente - vCrvOffs.emplace_back( ConvertCurveToComposite( Release( pOffLongestCrv))) ; - // passo alla successiva - pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ; - } - } - if ( bExtAllClose) { // se ho inserito il loop esterno - // inserisco la curva come isola - if ( ! pSfrToOffset->AddIntLoop( Release( pCrvIsl))) - return false ; - } - else { - // le isole saranno da loop esterni - pCrvIsl->Invert() ; // seguo il percorso di lavoro - if ( ! pSfrToOffset->AddExtLoop( Release( pCrvIsl))) - return false ; - } - } - } - } - - // vettore di curve temporanee ( da confrontare con la regione limite) - ICRVCOMPOPOVECTOR vCrvCompoRes_tmp ; - - if ( ! bHasIslands) { // se non avevo isole... - // restituisco le curve di svuotatura calcolate dai chiusi del loop esterno - for ( int i = 0 ; i < int( vCrvOffs.size()) ; ++ i) - vCrvCompoRes_tmp.emplace_back( Release( vCrvOffs[i])) ; - bAllRemoved = true ; // aggiornamento Flag - } - else { // se avevo isole - // i percorsi sono definiti dall'Offset della regione rimossa - // NB. Se ho inserito solo isole, allora l'Offset va verso l'esterno - // Se ho inserito sia il loop esterno che le isole, allora l'Offset è interno - // La superficie la Oriento sempre con normale Z_AX - if ( AreOppositeVectorApprox( pSfrToOffset->GetNormVersor(), Z_AX)) - pSfrToOffset->Invert() ; - double dOffs = PockParams.dRad ; - if ( bExtAllClose) - dOffs *= -1 ; - pSfrToOffset->Offset( dOffs, ICurve::OFF_FILLET) ; - if ( pSfrToOffset->IsValid() && pSfrToOffset->GetChunkCount() > 0) { - for ( int c = 0 ; c < pSfrToOffset->GetChunkCount() ; ++ c) - for ( int l = 0 ; l < pSfrToOffset->GetLoopCount( c) ; ++ l) { - // recupero il loop - PtrOwner pCrvLoop( ConvertCurveToComposite( pSfrToOffset->GetLoop( c, l))) ; - if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid()) - return false ; - if ( l > 0) // se isola, inverto il senso di percorrenza - pCrvLoop->Invert() ; - vCrvCompoRes_tmp.emplace_back( Release( pCrvLoop)) ; - } - bAllRemoved = true ; + // 2) e 3) + bValidIslands = ( ( nCurrTmpProp == 0 && bExtAllOpen) || + ( nCurrTmpProp == 1 && bExtAllClose)) ; } + if ( ! bValidIslands) + return true ; + // nel caso 2) devo inserire le curve + // creo una regione formata solo dalla isole + PtrOwner pSrfIslands( CreateSurfFlatRegion()) ; + if ( IsNull( pSrfIslands)) + return false ; + for ( int i = 1 ; i < pSfrChunk->GetLoopCount( 0) ; ++ i) + pSrfIslands->AddExtLoop( pSfrChunk->GetLoop( 0, i)) ; + pSrfIslands->Offset( PockParams.dRad + PockParams.dRadialOffset, ICurve::OFF_FILLET) ; + for ( int c = 0 ; c < pSrfIslands->GetChunkCount() ; ++ c) + for ( int l = 0 ; l < pSrfIslands->GetLoopCount( l) ; ++ l) + vCrvCompoRes_tmp.emplace_back( ConvertCurveToComposite( pSrfIslands->GetLoop( c, l))) ; } + // se non ho ottenuto curve, allora ho finito if ( vCrvCompoRes_tmp.empty()) return true ; - // se richiesta inversione, cambio l'orientamento delle curve ottenute - if ( PockParams.bInvert) { - for ( int i = 0 ; i < int( vCrvCompoRes_tmp.size()) ; ++ i) - vCrvCompoRes_tmp[i]->Invert() ; - } + bAllRemoved = true ; - // recupero la superficie limite ( se esiste ed è valida) + // recupero la superficie limite ( se esiste ed è valida) PtrOwner pSfrLimit( CreateSurfFlatRegion()) ; if ( IsNull( pSfrLimit)) return false ; @@ -1902,7 +2013,7 @@ GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParam 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 + pSfrLimit->Offset( PockParams.dRad + PockParams.dRadialOffset - 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 ; @@ -1923,55 +2034,16 @@ GetPocketCurvesByCloseEdges( const ISurfFlatRegion* pSfrChunk, const PocketParam swap( vCrvCompoRes_tmp, vCrvCompoRes_tmp_Splitted) ; } - // imposto le Feed per tali curve e aggiungo eventuale entrata da fuori + // salvo come primo tempParam l'offset massimo della regione ( servirà per la Feed) for ( int i = 0 ; i < int( vCrvCompoRes_tmp.size()) ; ++ i) { - /* - Idea : Feed proporzionale al minimo Offset per annullare la regione ? - -> Massimo parametro sui bisettori di VORONOI - */ - double dFeed ; - GetFeedForParam( 2 * dMaxOffs, PockParams, dFeed) ; - AssignCustomFeed( vCrvCompoRes_tmp[i], PockParams, dFeed) ; - // ricavo punto di inizio e vettore tangente - Point3d ptStart ; vCrvCompoRes_tmp[i]->GetStartPoint( ptStart) ; - Vector3d vtStart ; vCrvCompoRes_tmp[i]->GetStartDir( vtStart) ; - // recupero il punto di caduta dell'utensile - Point3d ptFall = ptStart - vtStart * ( 2 * PockParams.dRad + PockParams.dOpenMinSafe) ; - // controllo che il tool non sia interno alla regione limite - if ( pSfrLimit->IsValid()) { - PtrOwner pCrvToolShape( CreateCurveArc()) ; - if ( IsNull( pCrvToolShape) || ! pCrvToolShape->Set( ptFall, Z_AX, PockParams.dRad - 100 * EPS_SMALL)) - return false ; - 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 minima - } - else { // se trovo intersezione, provo a ruotare di 90° - vtStart.Rotate( Z_AX, PockParams.bInvert ? - ANG_RIGHT : ANG_RIGHT) ; - ptFall = ptStart + vtStart * ( 2 * 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 - vCrvCompoRes_tmp[i]->SetTempProp( TMP_PROP_SINGLE_CURVE, 0) ; //nProp per curva singola - // inserisco la curva nel vettore finale - vCrvCompoRes.emplace_back( Release( vCrvCompoRes_tmp[i])) ; + vCrvCompoRes_tmp[i]->SetTempParam( dMaxOffs, 0) ; + vCrvCompoRes.emplace_back( Release( vCrvCompoRes_tmp[i])) ; // aggiungo la curva al vettore } return true ; } + //---------------------------------------------------------------------------- static bool ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams, ICRVCOMPOPOVECTOR& vCrvCompoRes, @@ -1998,6 +2070,11 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams, IC for ( int c = 0 ; c < nChunk ; ++ c) { // 0) controllo se seguendo i chiusi posso svuotare l'interno chunk + /* + nel caso in cui il chunk c-esimo può essere svuotata da una o più curve che seguono + il/i tratto/i chiuso/i, queste vengono salvate direttamente nei percorsi di svuotatura. + Il chuck c-esimo verrà poi ignorato ( quindi nessuna estensione presso gli aperti) + */ PtrOwner pSfrChunk( pSfr->CloneChunk( c)) ; if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid()) return false ; @@ -2005,7 +2082,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams, IC GetPocketCurvesByCloseEdges( pSfrChunk, PockParams, vCrvCompoRes, bIsAllRemoved) ; if ( bIsAllRemoved) { // se ho rimosso tutto, allora passo la chunk successivo ++ nChunkOneCurve ; // aumento il contatore - continue ; + continue ; // ignoro il chunk c-esimo } // vettore delle isole che userò ( le isole aperte piccole sono trascurate) @@ -2115,6 +2192,15 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams, IC } } + // se ho ottenuto delle curve singole, allora le provo a concatenare + // ( tenendo solo le curve al di fuori della superficie limite ( con Offset del raggio del tool) + // potrei doverle riconcatenare + if ( ! ChainCompoCurves( vCrvCompoRes)) + return false ; + // determino ora il punto di inizio, il tratto per il LeadIn e la Feed delle curve singole + if ( ! AdjustOpenCurves( vCrvCompoRes, PockParams)) + return false ; + // se ho rimosso tutti i Chunk con una singola curva... bSkipPocket = ( nChunk == nChunkOneCurve) ; if ( bSkipPocket) @@ -6127,7 +6213,12 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int PtrOwner pCrvCompoBorder( ConvertCurveToComposite( pSfrOffsVR->GetLoop( i, j))) ; if ( IsNull( pCrvCompoBorder) || ! pCrvCompoBorder->IsValid()) return false ; - if ( j > 0) // inverto l'orientamento delle curve interne ( offset delle isole trovate) + /* + Il materiale deve sempre trovarsi alla destra ( se bInvert -> alla sinistra) del tool + soltanto sul primo bordo; Nel caso di isole aperte o nelle passate di Offset intermedio + l'orientamente non ha importanza. + */ + if ( nIter != 0 && j > 0) // inverto l'orientamento delle curve interne ( offset delle isole trovate) pCrvCompoBorder->Invert() ; // controllo quali regioni di Offset possono essere sostituite bool bInsert = true ; From e853ff7f1374f7ad640cb96aee0464e4d94f0db4 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Fri, 12 Jul 2024 20:09:04 +0200 Subject: [PATCH 3/5] Aggiunto parametro per evitare casi ottimizzati --- CalcPocketing.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 238df29..68e0ad6 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -58,6 +58,7 @@ struct PocketParams { bool bAboveHead = true ; // flag per testa da sopra ( Z+) bool bSmooth = false ; // curve smussate bool bInvert = false ; // inversione dei percorsi + bool bAvoidOpt = false ; // flag per evitare casi ottimizzati Point3d ptStart = P_INVALID ; // punto d'inizio Point3d ptEnd = P_INVALID ; // punto di fine SurfFlatRegion SfrLimit ; // superficie limite per estensione lati aperti @@ -6107,9 +6108,9 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int // CONTROLLO PER CASI OTTIMIZZATI bool bHasIsland = ( pSrfPock->GetLoopCount( 0) > 1) ; - // se non ho isole e curva valida allora controllo casi ottimizzati - if ( ! bHasIsland && ( ! vCrvOrigChunkLoops.empty()) && ! IsNull( vCrvOrigChunkLoops[0])) { + if ( ! PockParams.bAvoidOpt && ! bHasIsland && + ( ! vCrvOrigChunkLoops.empty()) && ! IsNull( vCrvOrigChunkLoops[0])) { // --------------------------- caso spirale --------------------------------------- PtrOwner pCrvBorder( ConvertCurveToComposite( pSrfPock->GetLoop( 0, 0))) ; @@ -7242,7 +7243,7 @@ AddOneWay( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con //---------------------------------------------------------------------------- bool CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double dStep, double dAngle, - int nType, bool bSmooth, bool bInvert, ISurfFlatRegion* pSfrLimit, ICRVCOMPOPOVECTOR& vCrvCompoRes) + int nType, bool bSmooth, bool bInvert, bool bAvoidOpt, ISurfFlatRegion* pSfrLimit, ICRVCOMPOPOVECTOR& vCrvCompoRes) { // controllo dei parametri if ( pSfr == nullptr || ! pSfr->IsValid() || @@ -7262,6 +7263,7 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double myParams.dAngle = dAngle ; myParams.dSideStep = dStep ; myParams.bInvert = bInvert ; + myParams.bAvoidOpt = bAvoidOpt ; if ( pSfrLimit != nullptr && pSfrLimit->IsValid()) myParams.SfrLimit.CopyFrom( pSfrLimit) ; From 21feed172d9f0982d124ecd04b40117793d5e5fd Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 15 Jul 2024 07:08:11 +0200 Subject: [PATCH 4/5] EgtGeomKernel : - in CollisionAvoid corretto assegnamento riferimento (da fare prima del calcolo di hashgrids) - in CalcPocketing corretti i punti che lasciavano memory leaks e migliorie stilistiche varie. --- CAvToolSurfTm.cpp | 10 ++-- CalcPocketing.cpp | 126 ++++++++++++++++++++++++---------------------- 2 files changed, 70 insertions(+), 66 deletions(-) diff --git a/CAvToolSurfTm.cpp b/CAvToolSurfTm.cpp index f911a90..7698de6 100644 --- a/CAvToolSurfTm.cpp +++ b/CAvToolSurfTm.cpp @@ -55,7 +55,7 @@ CAvToolSurfTm::Clear( void) // reset utensile m_Tool.Clear() ; // reset riferimento - m_frMove.Reset() ; + m_frMove.Reset( false) ; return true ; } @@ -179,11 +179,11 @@ CAvToolSurfTm::TestSeries( PNTUVECTOR& vPntM, const Vector3d& vtDir, const Vecto frMove.Set( ORIG, vtMove) ; // Se riferimento di movimento non presente o diverso dal calcolato if ( ! m_frMove.IsValid() || ! AreSameFrame( frMove, m_frMove)) { + // Salvo nuovo riferimento + m_frMove = frMove ; // Ricalcolo HashGrid if ( ! PrepareHashGrid()) return false ; - // Salvo nuovo riferimento - m_frMove = frMove ; } // Determino il numero di punti dell'insieme m_nTotPnt = int( vPntM.size()) ; @@ -295,11 +295,11 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& frMove.Set( ORIG, vtMove) ; // Se riferimento di movimento non presente o diverso dal calcolato if ( ! m_frMove.IsValid() || ! AreSameFrame( frMove, m_frMove)) { + // Salvo nuovo riferimento + m_frMove = frMove ; // Ricalcolo HashGrid if ( ! PrepareHashGrid()) return false ; - // Salvo nuovo riferimento - m_frMove = frMove ; } // Determino il numero di punti del path m_nTotPnt = int( lPntM.size()) ; diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 68e0ad6..0289c3f 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -520,7 +520,7 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved_offs } // clono la superificie ( valida) - PtrOwner pSrf_Removed_offs_clone( CloneSurfFlatRegion( pSrfRemoved_offs)) ; + PtrOwner pSrf_Removed_offs_clone( pSrfRemoved_offs->Clone()) ; if ( IsNull( pSrf_Removed_offs_clone) || ! pSrf_Removed_offs_clone->IsValid() || pSrf_Removed_offs_clone->GetChunkCount() == 0) return true ; // esco ( sempre con Feed Minima) @@ -577,11 +577,11 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved_offs AreSamePointApprox( aInfo.IciA[0].ptI, aInfo.IciA[1].ptI)) continue ; // passo al successivo se non c'è overlap o se i punti coicidono // tratto precedente - PtrOwner pCrv_before( CloneCurveComposite( pCrv)) ; + PtrOwner pCrv_before( pCrv->Clone()) ; if ( ! pCrv_before->TrimEndAtParam( aInfo.IciA[0].dU)) pCrv_before->Clear() ; // se troppo piccolo, elimino // tratto successivo - PtrOwner pCrv_after( CloneCurveComposite( pCrv)) ; + PtrOwner pCrv_after( pCrv->Clone()) ; if ( ! pCrv_after->TrimStartAtParam( aInfo.IciA[1].dU)) pCrv_after->Clear() ; // se troppo piccolo, elimino // tratto di overlap @@ -632,7 +632,7 @@ AssignFeedSpiral( ICurveComposite* pCrv, const ISurfFlatRegion* pSrfRemoved_offs double dLen = EPS_SMALL ; pCrv->GetCurve( u)->GetLength( dLen) ; if ( dLen < dToll + 5 * EPS_SMALL) { - PtrOwner pCrvCompo( CloneCurveComposite( pCrv)) ; + PtrOwner pCrvCompo( pCrv->Clone()) ; if ( ! pCrvCompo->TrimStartAtParam( u)) pCrvCompo->Clear() ; if ( ! pCrvCompo->TrimEndAtLen( dLen + PockParams.dRad * 2)) @@ -823,7 +823,7 @@ GetParamForPtStartOnEdge( const ICurve* pCrvCheck, const ICurveComposite* pCrvCo // clono le curve PtrOwner pCrv( pCrvCheck->Clone()) ; - PtrOwner pCompo( CloneCurveComposite( pCrvCompo)) ; + PtrOwner pCompo( pCrvCompo->Clone()) ; if ( IsNull( pCrv) || IsNull( pCompo)) return false ; ICRVCOMPOPOVECTOR vCrvNoInters ; @@ -857,8 +857,7 @@ GetParamForPtStartOnEdge( const ICurve* pCrvCheck, const ICurveComposite* pCrvCo return false ; double dSubArc = -1 ; if ( pCrv->GetType() == CRV_ARC) { - PtrOwner pCrvArc( GetCurveArc( pCrv->Clone())) ; - if ( IsNull( pCrvArc) || ! GetCoeffLinArc( pCrvArc, dDiam, dSubArc)) + if ( ! GetCoeffLinArc( GetCurveArc( pCrv), dDiam, dSubArc)) return false ; } double dDiv = dSubArc < 0 ? dDiam : dSubArc ; @@ -881,7 +880,7 @@ GetParamForPtStartOnEdge( const ICurve* pCrvCheck, const ICurveComposite* pCrvCo if ( pCrv->GetPointD1D2( dParT, ICurve::FROM_PLUS, ptTest, &vtPerpIn)) { - PtrOwner pCompoClone( CloneCurveComposite( pCompo)) ; + PtrOwner pCompoClone( pCompo->Clone()) ; if ( IsNull( pCompoClone)) return false ; double dU ; @@ -1220,7 +1219,7 @@ GetHomogeneousParts( ICurveComposite* pCrvCompo, const PocketParams& PockParams, if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || pCrvCompo->GetCurveCount() == 0) // se curva non valida return true ; - // la curva ha sia tratti aperti che tratti chiusi, quindi sposto l'inizio a metà del tratto più lungo ( se richisto)... + // la curva ha sia tratti aperti che tratti chiusi, quindi sposto l'inizio a metà del tratto più lungo ( se richiesto)... ICRVCOMPOPOVECTOR vCrvNULL ; AdjustContourStart( pCrvCompo, PockParams, vCrvNULL, false, P_INVALID) ; @@ -1289,7 +1288,7 @@ CreateSurfFrIncidence( const ICurveComposite* pCrv, const Vector3d& vtTanS_, con if ( OffsCrv.Make( pCrv, - dRad, ICurve::OFF_FILLET)) { PtrOwner pMyCrv( OffsCrv.GetLongerCurve()) ; if ( ! IsNull( pMyCrv) && pMyCrv->IsValid()) - pOffsInt.Set( Release( pMyCrv)) ; + pOffsInt.Set( pMyCrv) ; } // recupero gli estremi della curva aperta corrente @@ -1388,7 +1387,7 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI // scorro il vettore creato... for ( int c = 0 ; c < int( vCrvToCheck.size()) ; ++ c) { // 1) recupero la curva corrente - PtrOwner pCrvCurr( CloneCurveComposite( vCrvToCheck[c])) ; + PtrOwner pCrvCurr( vCrvToCheck[c]->Clone()) ; if ( IsNull( pCrvCurr) || ! pCrvCurr->IsValid()) return false ; // 2) ricavo i tratti con proprietà uniformi ( Aperti/Chiusi ) @@ -1453,7 +1452,7 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI // esso ! if ( PockParams.SfrLimit.IsValid()) { // recupero la superficie limite - PtrOwner pSfrLimit( GetSurfFlatRegion( PockParams.SfrLimit.Clone())) ; + PtrOwner pSfrLimit( PockParams.SfrLimit.Clone()) ; if ( IsNull( pSfrLimit) || ! pSfrLimit->IsValid()) return false ; // piccolo Offset per sicurezza @@ -1479,17 +1478,21 @@ AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVECTOR& vCrvI return false ; // se estremi in comune, la curva cercata è la seguente if ( pCrvEL->IsPointOn( ptS, 300 * EPS_SMALL) && pCrvEL->IsPointOn( ptE, 300 * EPS_SMALL)) { - if ( ! pNewSfrInc->IsValid()) // se la nuova regione di incidenza è vuota... - pNewSfrInc.Set( pSfrInc->CloneChunk( i)) ; // aggiorno... - else // se la nuova regione di incidenza non è vuota... - if ( ! pNewSfrInc->Add( * pSfrInc->CloneChunk( i))) // aggiungo... + // se la nuova regione di incidenza è vuota, aggiorno + if ( ! pNewSfrInc->IsValid()) + pNewSfrInc.Set( pSfrInc->CloneChunk( i)) ; + // se la nuova regione di incidenza non è vuota, aggiungo + else { + PtrOwner pSfrToAdd( pSfrInc->CloneChunk( i)) ; + if ( IsNull( pSfrToAdd) || ! pNewSfrInc->Add( *pSfrToAdd)) return false ; + } } } // definisco quindi la nuova regione di incidenza if ( ! pNewSfrInc->IsValid()) return false ; - pSfrInc.Set( Release( pNewSfrInc)) ; + pSfrInc.Set( pNewSfrInc) ; } } @@ -2126,7 +2129,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams, IC int nCurrTmpProp = -1 ; int nPrecTmpProp = -1 ; bool bIsMixed = false ; - PtrOwner pCrvIsl( ConvertCurveToComposite( vCrvIsl[i]->Clone())) ; + PtrOwner pCrvIsl( vCrvIsl[i]->Clone()) ; if ( IsNull( pCrvIsl) || ! pCrvIsl->IsValid()) return false ; for ( int u = 0 ; u < pCrvIsl->GetCurveCount() && ! bIsMixed ; ++ u) { @@ -2187,9 +2190,11 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams, IC // aggiungo il Chunk alla superficie finale if ( pSrfFinal->GetChunkCount() == 0) pSrfFinal.Set( pSfr->CloneChunk( c)) ; - else - if ( ! pSrfFinal->Add( *pSfr->CloneChunk( c))) + else { + PtrOwner pSfrToAdd( pSfr->CloneChunk( c)) ; + if ( IsNull( pSfrToAdd) || ! pSrfFinal->Add( *pSfrToAdd)) return false ; + } } } @@ -2308,7 +2313,7 @@ GetParamOnOpenSide( const ICurveComposite* pCompo, const ICRVCOMPOPOVECTOR& vOth // cerco il parametro di tale curva (0 < dParIn < 1) migliore per l'entrata if ( GetParamForPtStartOnEdge( pCrv, pCompo, vOtherCrv, PockParams, dParIn)) { pCrv->GetPointD1D2( dParIn, ICurve::FROM_PLUS, ptMid) ; - PtrOwner pCompoClone( CloneCurveComposite( pCompo)) ; + PtrOwner pCompoClone( pCompo->Clone()) ; if ( IsNull( pCompoClone)) return false ; double dU ; @@ -2537,7 +2542,7 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams, return false ; // clono le curva su cui devo entrare - PtrOwner pCrv( CloneCurveComposite( pCrvOffsAct)) ; + PtrOwner pCrv( pCrvOffsAct->Clone()) ; if ( IsNull( pCrv)) return false ; @@ -2603,7 +2608,7 @@ SetPtStartForPath( ICurveComposite* pCrvOffsAct, const PocketParams& PockParams, bOk = false ; } if ( bOk) - vOtherCrv.emplace_back( ConvertCurveToComposite( vCrvLoops[i]->Clone())) ; + vOtherCrv.emplace_back( vCrvLoops[i]->Clone()) ; } // cerchiamo un punto valido per l'entrata ... @@ -2760,7 +2765,7 @@ GetOptCrvIndex( const ISurfFlatRegion* pSfrOrig, const ISurfFlatRegion* pSfrChun // effettuo un Offset del Chunk per simulare la creazione degli n Chunks double dOffs = PockParams.dRad + PockParams.dRadialOffset ; - PtrOwner pSfrRefChunk( CloneSurfFlatRegion( pSfrChunk)) ; + PtrOwner pSfrRefChunk( pSfrChunk->Clone()) ; if ( IsNull( pSfrRefChunk) || ! pSfrRefChunk->Offset( - dOffs, ICurve::OFF_FILLET)) return false ; @@ -2829,7 +2834,7 @@ OptimizedSpiralCirle( const ICurveComposite* pCrvCompo, const double dToll, doub return false ; // porto la curva nel sistema di riferimento corrente ( dopo averla clonata) - PtrOwner pCrvLoc( CloneCurveComposite( pCrvCompo)) ; + PtrOwner pCrvLoc( pCrvCompo->Clone()) ; if ( IsNull( pCrvLoc) || ! pCrvLoc->IsValid() || ! pCrvLoc->ToLoc( frCurr)) return false ; @@ -2999,7 +3004,7 @@ GetBoxCrvOptTrap( const int nCrv, const ICurveComposite* pCrvCompo, const double return false ; // porto la curva Compo ( clonandola) nel frame e calcolo il suo BBox BBox3d BBox ; - PtrOwner pCrvCompo_c( CloneCurveComposite( pCrvCompo)) ; + PtrOwner pCrvCompo_c( pCrvCompo->Clone()) ; if ( IsNull( pCrvCompo_c) || ! pCrvCompo_c->IsValid() || ! pCrvCompo_c->ToLoc( frTrap) || ! pCrvCompo_c->GetLocalBBox( BBox)) @@ -3046,8 +3051,8 @@ PreparareTrapezoidTwoBases( const ICurveComposite* pCrvCompo, const double dDiam // le parti tra le due basi devono essere tutte omogenee ( o tutte aperte o tutte chiuse) // pCrvTest0 sarà la parte destra, pCrvTest1 la parte sinistra Point3d ptSB0, ptSB1 ,ptEB0, ptEB1 ; - PtrOwner pCrvTest0( CloneCurveComposite( pCrvCompo)) ; - PtrOwner pCrvTest1( CloneCurveComposite( pCrvCompo)) ; + PtrOwner pCrvTest0( pCrvCompo->Clone()) ; + PtrOwner pCrvTest1( pCrvCompo->Clone()) ; pCrvCompo->GetCurve( nBase)->GetStartPoint( ptSB0) ; pCrvCompo->GetCurve( nBase)->GetEndPoint( ptEB0) ; pCrvCompo->GetCurve( nSecondBase)->GetStartPoint( ptSB1) ; @@ -4563,10 +4568,10 @@ CalcBoundedSmoothedLink( const Point3d& ptStart, const Vector3d& vtStart, const } } - PtrOwner pCrvCompo_noSmooth( CloneCurveComposite( pCompo)) ; + PtrOwner pCrvCompo_noSmooth( pCompo->Clone()) ; if ( ! ModifyCurveToSmoothed( pCompo, PockParams, 0.05, 0.05, true) || ! pCompo->IsValid()) - pCompo.Set( Release( pCrvCompo_noSmooth)) ; + pCompo.Set( pCrvCompo_noSmooth) ; pCrvLink->AddCurve( Release( pCompo)) ; return true ; @@ -4737,7 +4742,7 @@ GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICU PtrOwner pSrfToolRegLinki( GetSurfFlatRegionFromFatCurve( Release( pCrvLink_i), PockParams.dRad + 5 * EPS_SMALL, false, false)) ; if ( ! IsNull( pSrfToolRegLinki)) { if ( ! pSrfTool_Links->IsValid() || pSrfTool_Links->GetChunkCount() == 0) - pSrfTool_Links.Set( GetBasicSurfFlatRegion( Release( pSrfToolRegLinki))) ; + pSrfTool_Links.Set( pSrfToolRegLinki) ; else pSrfTool_Links->Add( *pSrfToolRegLinki) ; } @@ -4755,13 +4760,13 @@ GetUnclearedRegion( ICRVCOMPOPOVECTOR& vFirstOffs, ICRVCOMPOPOVECTOR& vCrvs, ICU return false ; // aggiorno la superificie svuotata - PtrOwner pCrvOffs_i( CloneCurveComposite( vCrvs[i])) ; + PtrOwner pCrvOffs_i( vCrvs[i]->Clone()) ; if ( IsNull( pCrvOffs_i)) return false ; PtrOwner pSrfToolRegOffi( GetSurfFlatRegionFromFatCurve( Release( pCrvOffs_i) , PockParams.dRad + 5 * EPS_SMALL, false, false)) ; if ( ! IsNull( pSrfToolRegOffi)) { if ( ! pSrfTool_Offs->IsValid() || pSrfTool_Offs->GetChunkCount() == 0) - pSrfTool_Offs.Set( Release( pSrfToolRegOffi)) ; + pSrfTool_Offs.Set( pSrfToolRegOffi) ; else pSrfTool_Offs->Add( *pSrfToolRegOffi) ; } @@ -4795,12 +4800,11 @@ RemoveFirstLoopFromSfr( ISurfFlatRegion* pSrfOrig) PtrOwner pSrfHelp( CreateBasicSurfFlatRegion()) ; if ( IsNull( pSrfHelp)) return false ; - PtrOwner pCrvMiniChunkBorder( GetBasicCurveComposite( pSrfOrig->GetLoop( c, 0))) ; - pSrfHelp->AddExtLoop( pCrvMiniChunkBorder->Clone()) ; + pSrfHelp->AddExtLoop( pSrfOrig->GetLoop( c, 0)) ; if ( c == 1) - pSrfRes.Set( pSrfHelp->Clone()) ; + pSrfRes.Set( pSrfHelp) ; else - pSrfRes->Add( *( pSrfHelp)) ; + pSrfRes->Add( *pSrfHelp) ; } // restituisco pSrfOrig->Clear() ; @@ -5942,8 +5946,8 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con // accorcio la curva per raccordarmi in tangenza con la successiva if ( int( vOffs.size()) > 1) { // clono le curve i ed i+1 esime ( nel caso non riuscissi ad accorciarle o raccordarle ) - PtrOwner pCrv_i( CloneCurveComposite( vOffs[i])) ; - PtrOwner pCrv_ii( CloneCurveComposite( vOffs[i+1])) ; + PtrOwner pCrv_i( vOffs[i]->Clone()) ; + PtrOwner pCrv_ii( vOffs[i+1]->Clone()) ; if ( IsNull( pCrv_i) || IsNull( pCrv_ii) || ! pCrv_i->IsValid() || ! pCrv_ii->IsValid()) return false ; // creo la curva che le collegherà @@ -5956,8 +5960,8 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con // se non sono riuscito, cerco una strada più semplice // ripristino le curve pCrvLink->Clear() ; - vOffs[i].Set( Release( pCrv_i)) ; // chiuso - vOffs[i+1].Set( Release( pCrv_ii)) ; // chiuso + vOffs[i].Set( pCrv_i) ; // chiuso + vOffs[i+1].Set( pCrv_ii) ; // chiuso // recupero i vettori tangente iniziali ( le curve sono chiuse ) Vector3d vtS, vtE ; if ( ! vOffs[i]->GetStartDir( vtS) || ! vOffs[i+1]->GetStartDir( vtE)) @@ -5981,7 +5985,7 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con // imposto il punto iniziale della curva successiva ( i+1 esima) vOffs[i+1]->ChangeStartPoint( dUNewE) ; - PtrOwner pCrvNewOffs( CloneCurveComposite( vOffs[i])) ; + PtrOwner pCrvNewOffs( vOffs[i]->Clone()) ; if ( dUNewS > EPS_SMALL) { pCrvNewOffs.Set( ConvertCurveToComposite( vOffs[i]->CopyParamRange( 0, dUNewS))) ; // sostituisco la curva i esima con quella tagliata @@ -5989,7 +5993,7 @@ CreateSpiralPocketingPath( ICRVCOMPOPOVECTOR& vOffs, ICURVEPOVECTOR& vLinks, con } // aggiorno il collegamento - vLinks[i+1].Set( Release( pCrvLink)) ; + vLinks[i+1].Set( pCrvLink) ; } @@ -6176,7 +6180,7 @@ CalcSpiral( const ISurfFlatRegion* pSrfPock, const PocketParams& PockParams, int ICRVCOMPOPOVECTOR vOffs ; // vettore delle curve di offset ICRVCOMPOPOVECTOR vOffsFirstCurve ; // curve di primo offset - PtrOwner pSrfAct( CloneSurfFlatRegion( pSrfToWork)) ; // regione attuale + PtrOwner pSrfAct( pSrfToWork->Clone()) ; // regione attuale if ( IsNull( pSrfAct) || pSrfAct->GetChunkCount() == 0) return false ; @@ -6711,8 +6715,8 @@ CalcZigZag( const ISurfFlatRegion* pSrfZigZag, const PocketParams& PockParams, I } if ( nStatus == 2) { // ho precedentemente aggiunto il bordo di un'isola, quindi mi salvo il secondo segmento - PtrOwner pSeg1( CloneCurveComposite( pLastSeg)) ; - PtrOwner pSeg2( CloneCurveComposite( pLineCompo)) ; + PtrOwner pSeg1( pLastSeg->Clone()) ; + PtrOwner pSeg2( pLineCompo->Clone()) ; if ( IsNull( pSeg1) || IsNull( pSeg2)) return false ; @@ -6916,7 +6920,7 @@ AddSpiralOut( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; ++ c) { // copio il chunk c-esimo - PtrOwner pSrfChunk( GetSurfFlatRegion( pSrfPock->CloneChunk( c))) ; + PtrOwner pSrfChunk( pSrfPock->CloneChunk( c)) ; if ( IsNull( pSrfChunk)) return false ; @@ -6982,7 +6986,7 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con for ( int c = 0 ; c < pSrfPock->GetChunkCount() ; ++ c) { // copio il chunk c-esimo - PtrOwner pSrfChunk(( pSrfPock->CloneChunk( c))) ; + PtrOwner pSrfChunk( pSrfPock->CloneChunk( c)) ; if ( IsNull( pSrfChunk)) return false ; @@ -6996,7 +7000,7 @@ AddZigZag( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con pSrfChunk->ToLoc( frPocket) ; // creo la regione per il percorso a ZigZag - PtrOwner pSrfZigZag( CloneSurfFlatRegion( pSrfChunk)) ; + PtrOwner pSrfZigZag( pSrfChunk->Clone()) ; if ( ! pSrfZigZag->Offset( - dOffs, ICurve::OFF_FILLET)) return false ; @@ -7053,7 +7057,7 @@ OptimizeChunkOneWay( ISurfFlatRegion* pSrfOrig, ISURFFRPOVECTOR& vSrfIdeal) vSrfIdeal.clear() ; // clono la superficie passata alla funzione - PtrOwner pSrfToPock( CloneSurfFlatRegion( pSrfOrig)) ; + PtrOwner pSrfToPock( pSrfOrig->Clone()) ; if ( IsNull( pSrfToPock) || pSrfToPock->GetChunkCount() == 0) return false ; @@ -7068,20 +7072,20 @@ OptimizeChunkOneWay( ISurfFlatRegion* pSrfOrig, ISURFFRPOVECTOR& vSrfIdeal) return false ; if ( vChunksAvailable[c] == 1) { // se Chunk valido... // prendo la curva esterna - PtrOwner pCrvExt( ConvertCurveToComposite( pSrfToPock->GetLoop( c, 0))) ; + PtrOwner pCrvExt( pSrfToPock->GetLoop( c, 0)) ; if ( IsNull( pCrvExt)) return false ; // inserisco il chunk c-esimo ( curva per curva, così non perdo le temp prop) pSrfIdeal->AddExtLoop( pCrvExt->Clone()) ; // ... inizio a creare la regione ideale da esso for ( int l = 1 ; l < pSrfToPock->GetLoopCount( c) ; ++ l) - pSrfIdeal->AddIntLoop( ConvertCurveToComposite( pSrfToPock->GetLoop( c, l))) ; + pSrfIdeal->AddIntLoop( pSrfToPock->GetLoop( c, l)) ; // il chunk c-esimo non è più disponibile... vChunksAvailable[c] = -1 ; // scorro tutti gli altri chunk i-esimi ancora disponibili for ( int i = 0 ; i < int( vChunksAvailable.size()) ; ++ i) { if ( vChunksAvailable[i] == 1) { // prendo la curva esterna del chunk i-esimo disponibile - PtrOwner pCrvExtC( ConvertCurveToComposite( pSrfToPock->GetLoop( i, 0))) ; + PtrOwner pCrvExtC( pSrfToPock->GetLoop( i, 0)) ; if ( IsNull( pCrvExtC)) return false ; // classifico i bordi esterni ( se il bordo del chunk c-esimo contiene o è contenuto nel loop @@ -7091,11 +7095,11 @@ OptimizeChunkOneWay( ISurfFlatRegion* pSrfOrig, ISURFFRPOVECTOR& vSrfIdeal) intCC.GetCurveClassification( 0, EPS_SMALL, ccClass) ; intCC.GetCurveClassification( 1, EPS_SMALL, ccClass1) ; if (( ccClass.size() == 1 && ccClass[0].nClass == CRVC_IN) || - ( ccClass1.size() == 1 && ccClass1[0].nClass == CRVC_IN)) { + ( ccClass1.size() == 1 && ccClass1[0].nClass == CRVC_IN)) { // inserisco il chunk i-esimo ( curva per curva, così non perdo le temp prop) - pSrfIdeal->AddExtLoop( ConvertCurveToComposite( pSrfToPock->GetLoop( i, 0))) ; + pSrfIdeal->AddExtLoop( pSrfToPock->GetLoop( i, 0)) ; for ( int l = 1 ; l < pSrfToPock->GetLoopCount( i) ; ++ l) - pSrfIdeal->AddIntLoop( ConvertCurveToComposite( pSrfToPock->GetLoop( i, l))) ; + pSrfIdeal->AddIntLoop( pSrfToPock->GetLoop( i, l)) ; vChunksAvailable[i] = -1 ; // chunk j-esimo non più disponibile // NB: Se il chunk i-esimo contiene la pSrfIdeal ( quindi chunk i-esimo unito ad eventuali altri chunk // j-esimi precedenti -> prendo come bordo esterno di riferimento il suo e ricontrollo dall'inizio i @@ -7114,7 +7118,7 @@ OptimizeChunkOneWay( ISurfFlatRegion* pSrfOrig, ISURFFRPOVECTOR& vSrfIdeal) } - return ( int( vSrfIdeal.size() != 0)) ; + return ( ! vSrfIdeal.empty()) ; } //---------------------------------------------------------------------------- @@ -7150,7 +7154,7 @@ AddOneWay( const ISurfFlatRegion* pSrfPock, const ISurfFlatRegion* pSfrOrig, con for ( int nIs = 0 ; nIs < int( vSrfFlat.size()) ; ++ nIs) { // copio la superficie ideale - PtrOwner pSrfIdeal( CloneSurfFlatRegion( vSrfFlat[nIs])) ; + PtrOwner pSrfIdeal( vSrfFlat[nIs]->Clone()) ; if ( IsNull( pSrfIdeal)) return false ; @@ -7275,7 +7279,7 @@ CalcPocketing( const ISurfFlatRegion* pSfr, double dRad, double dRadOffs, double if ( ! frLoc.Set( ptCenter, vtN)) return false ; // porto la superficie da svuotare in tale sistema - PtrOwner pSfrAdj( CloneSurfFlatRegion( pSfr)) ; + PtrOwner pSfrAdj( pSfr->Clone()) ; if ( IsNull( pSfrAdj) || ! pSfrAdj->ToLoc( frLoc)) return false ; // porto la superficie limite ( se valida) in tale sistema @@ -7469,7 +7473,7 @@ AdjustLinkDifferentY( const ICurve* pCrvSegPrec, const ICurve* pCrvSegSucc, pSfrTrap->Invert() ; // effettuo un piccolo Offset per una maggiore tolleranza ( se possibile) - PtrOwner pSfrTrap_c( CloneSurfFlatRegion( pSfrTrap)) ; + PtrOwner pSfrTrap_c( pSfrTrap->Clone()) ; if ( IsNull( pSfrTrap_c)) return false ; if ( ! pSfrTrap->Offset( - PockParams.dRad / 5, ICurve::OFF_CHAMFER)) @@ -7558,7 +7562,7 @@ AdjustLinkZigZagInfill( ICurveComposite* pCrvCompo, const PocketParams& PockPara } // se non ho mai trovato link non validi, lascio la curva invariata if ( vIntervals.empty()) - vNewCrv.emplace_back( CloneCurveComposite( pCrvCompo)) ; + vNewCrv.emplace_back( pCrvCompo->Clone()) ; else { // per ogni intervallo... for ( int i = 0 ; i < int( vIntervals.size()) ; ++ i) From 4748bd5ac888a0ae6b9381c40bad0aaf01df73aa Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Mon, 15 Jul 2024 13:28:14 +0200 Subject: [PATCH 5/5] EgtGeomKernel : - In CalcPocketing corretta la gestione delle isole aperte mediante MaxOffset. --- CalcPocketing.cpp | 44 +++++--------------------------------------- 1 file changed, 5 insertions(+), 39 deletions(-) diff --git a/CalcPocketing.cpp b/CalcPocketing.cpp index 0289c3f..966bf33 100644 --- a/CalcPocketing.cpp +++ b/CalcPocketing.cpp @@ -1670,39 +1670,6 @@ AdjustContourWithOpenEdges( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vCrvI return true ; } -//---------------------------------------------------------------------------- -static bool -CheckForRemovingIsland( const ICurveComposite* pCrvIslandBorder, double dOffs, bool bRemove) -{ - // controllo dei parametri - // NB. La curva dell'isola gira in senso orario, quindi l'offset va fatto in positivo - if ( pCrvIslandBorder == nullptr || ! pCrvIslandBorder->IsValid() || dOffs < EPS_SMALL) - return false ; - bRemove = false ; - - // controllo se l'isola è tutta aperta - for ( int u = 0 ; u < pCrvIslandBorder->GetCurveCount() ; ++ u) { - const ICurve* pCrv_u = pCrvIslandBorder->GetCurve( u) ; - if ( pCrv_u == nullptr) - return false ; - int nTmpProp0 = pCrv_u->GetTempProp( 0) ; - // se trovo una sottocurva che non è aperta, esco - if ( nTmpProp0 != 1) - return true ; - } - - // tutte le curva sono aperte, effettuo un offset per vedere se l'isola è da tenere - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCrvIslandBorder, dOffs, ICurve::OFF_FILLET)) - return false ; - - // nel caso l'Offset sparisca, all'ora l'isola non è necessaria - if ( OffsCrv.GetCurveCount() == 0) - bRemove = true ; - - return true ; -} - //---------------------------------------------------------------------------- static bool ChainCompoCurves( ICRVCOMPOPOVECTOR& vCrvCompo) @@ -2146,11 +2113,10 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams, IC } // se curva tutta aperta, controllo se l'isola può essere trascurata if ( nCurrTmpProp == 1) { - bool bRemove = false ; - if ( ! CheckForRemovingIsland( pCrvIsl, 2 * PockParams.dRad + 2 * PockParams.dRadialOffset, - bRemove)) - return false ; - if ( bRemove) // se da rimuovere passo all'isola successiva + // calcolo il massimo Offset + double dMaxOffs ; + CalcCurveLimitOffset( *pCrvIsl, dMaxOffs) ; + if ( dMaxOffs < 2 * PockParams.dRad + 2 * PockParams.dRadialOffset) continue ; // altrimenti, estendo l'isola aperta ( considero il loop esterno come "isola" per l'estensione) ICRVCOMPOPOVECTOR vCrvExtLoop ; vCrvExtLoop.emplace_back( pCrvEL->Clone()) ; @@ -2168,7 +2134,7 @@ ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const PocketParams& PockParams, IC SurfFlatRegionByContours SfrBC ; // per sicurezza analizzo ancora i Loop pCrvEL->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ; SfrBC.AddCurve( Release( pCrvEL)) ; // <--- Loop esterno - for ( int i = 0 ; i < ( int)vCrvToTIsland.size() ; ++ i) { + for ( int i = 0 ; i < int( vCrvToTIsland.size()) ; ++ i) { vCrvToTIsland[i]->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true, true) ; SfrBC.AddCurve( Release( vCrvToTIsland[i])) ; // <--- isole "valide" }