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.
This commit is contained in:
Riccardo Elitropi
2024-07-12 16:29:53 +02:00
parent a7be952e11
commit 95ff8b21b9
+230 -139
View File
@@ -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 <array>
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<ICurveComposite> 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<ISurfFlatRegion> 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<ICurveArc> 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<ICurve> 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<ISurfFlatRegion> 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<ICurve> 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<ICurveComposite> 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<ISurfFlatRegion> 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<ISurfFlatRegion> 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<ICurveArc> 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<ISurfFlatRegion> 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<ICurveComposite> 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 ;