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:
+230
-139
@@ -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 ;
|
||||
|
||||
Reference in New Issue
Block a user