EgtGeomKernel :

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