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 ;