EgtMachKernel :

- In Finiture e Sgrossature di lama aggiunta unificazione delle sezioni se posizionate vicine tra loro
- In Finitura Along5A migliorato il controllo delle collisioni tra lama e sezioni, aggiunto il collegamento di tipo "Standard"
- In finitura Along5A refactoring del codice.
This commit is contained in:
Riccardo Elitropi
2026-08-26 10:33:18 +02:00
parent 5d219687dc
commit a2cbf87b9d
4 changed files with 352 additions and 184 deletions
+2
View File
@@ -306,6 +306,8 @@ class Operation : public IUserObj
{ if ( ! m_bCurr) return false ; return AreSamePointEpsilon( ptP, m_ptCurr, 10 * EPS_SMALL) ; }
bool GetCurrCorr( Vector3d& vtCCurr) const
{ if ( ! m_bCurr) return false ; vtCCurr = m_vtCorr ; return true ; }
bool GetCurrTool( Vector3d& vtCTool) const
{ if ( ! m_bCurr) return false ; vtCTool = m_vtTool ; return true ; }
bool GetCurrAux( Vector3d& vtACurr) const
{ if ( ! m_bCurr) return false ; vtACurr = m_vtAux ; return true ; }
int AddRapidStart( const Point3d& ptP) ;
+292 -161
View File
@@ -2168,12 +2168,6 @@ SawFinishing::CalculateStraightAlong5AToolPath( int nAuxId, int nClId)
m_pMchMgr->SetWarning( 2655, "Warning in SawRoughing : Link not compatible with extension") ;
m_Params.m_nLeadLinkType = SAWFIN_LL_CENT ;
}
// se link di tipo Standard, questa viene convertita in Center, per la lavorazione corrente si effettuano le rotazioni della lama
// sempre al di fuori del grezzo
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_STD) {
m_pMchMgr->SetWarning( 2655, "Warning in SawRoughing : Link not compatible with extension") ;
m_Params.m_nLeadLinkType = SAWFIN_LL_CENT ;
}
// Recupero ed elaboro la linea guida
Point3d ptGdStart, ptGdEnd ;
@@ -2529,6 +2523,59 @@ SawFinishing::CalculateSection( int nSectGrpId, ICRVCOMPOPOVECTOR& vpSections) c
vpNucCrvs.back()->Invert() ;
}
// le curve ricavate vengo ordinate per X descrescente
// NB. prima le curve sono orientate per X decrescente, quindi ogni curva si muove verso sinistra; ora, se si hanno più sezioni, queste
// vengono lavorate oridinatamente da destra a sinistra
typedef pair<int,double> INDASC ; // coppia indice, ascissa
typedef vector<INDASC> INDASCVECTOR ; // vettore di coppie indice, ascissa
INDASCVECTOR vIAsc ; vIAsc.reserve( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
Point3d ptStart ;
if ( ! vpNucCrvs[i]->GetStartPoint( ptStart))
return false ;
vIAsc.emplace_back( i, ptStart.x) ;
}
sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) { return a.second > b.second ; }) ;
ICURVEPOVECTOR vpSortedSections ; vpSortedSections.reserve( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vIAsc) ; ++ i) {
int nOldPos = vIAsc[i].first ;
vpSortedSections.emplace_back( ::Release( vpNucCrvs[nOldPos])) ;
}
swap( vpSortedSections, vpNucCrvs) ;
// calcolo il Box delle sezioni e controllo quali posso unire tra di loro
if ( ssize( vpNucCrvs) > 1) {
const double TOL_STICK_SECTION = m_TParams.m_dThick + 10. * EPS_SMALL ;
BOXVECTOR vBBoxSection( ssize( vpNucCrvs), BBox3d()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
vpNucCrvs[i]->GetLocalBBox( vBBoxSection[i]) ;
vBBoxSection[i].Expand( TOL_STICK_SECTION / 2.) ; // espando per includere la tolleranza
}
// verifico quali sezioni posso unire tra di loro
ICRVCOMPOPOVECTOR vLinkedSection ; vLinkedSection.reserve( vpNucCrvs.size()) ;
vLinkedSection.resize( 1) ;
if ( ! vLinkedSection.back().Set( ConvertCurveToComposite( Release( vpNucCrvs[0]))))
return false ;
for ( int i = 1 ; i < ssize( vpNucCrvs) ; ++ i) {
// controllo se il Box corrente interseca il precedente
if ( vBBoxSection[i-1].OverlapsXY( vBBoxSection[i])) {
Point3d pt ; vpNucCrvs[i]->GetStartPoint( pt) ;
if ( IsNull( vLinkedSection.back()))
return false ;
vLinkedSection.back()->AddLine( pt) ;
vLinkedSection.back()->AddCurve( Release( vpNucCrvs[i])) ;
}
else {
vLinkedSection.resize( vLinkedSection.size() + 1) ;
if ( ! vLinkedSection.back().Set( ConvertCurveToComposite( Release( vpNucCrvs[i]))))
return false ;
}
}
vpNucCrvs.clear() ; vpNucCrvs.resize( vLinkedSection.size()) ;
for ( int i = 0 ; i < ssize( vLinkedSection) ; ++ i)
vpNucCrvs[i].Set( Release( vLinkedSection[i])) ;
}
// dalle sezioni recuperate eseguo l'Offset Radiale complessivo (evito così interferenze con sezioni differenti)
ICURVEPVECTOR vpMySections ; vpMySections.resize( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i)
@@ -2543,7 +2590,7 @@ SawFinishing::CalculateSection( int nSectGrpId, ICRVCOMPOPOVECTOR& vpSections) c
if ( ! vpSections.back().Set( CreateCurveComposite()) ||
! vpSections.back()->AddCurve( vMySections[i]->Clone()))
return false ;
// eseguo anche Offset lungo X
// eseguo Offset lungo X
OffsetCurveOnX OffsCrvX ;
if ( ! OffsCrvX.Make( vpSections.back(), 0.5 * m_TParams.m_dThick))
return false ;
@@ -2560,26 +2607,6 @@ SawFinishing::CalculateSection( int nSectGrpId, ICRVCOMPOPOVECTOR& vpSections) c
}
}
// le curve ricavate vengo ordinate per X descrescente
// NB. prima le curve sono orientate per X decrescente, quindi ogni curva si muove verso sinistra; ora, se si hanno più sezioni, queste
// vengono lavorate oridinatamente da destra a sinistra
typedef pair<int,double> INDASC ; // coppia indice, ascissa
typedef vector<INDASC> INDASCVECTOR ; // vettore di coppie indice, ascissa
INDASCVECTOR vIAsc ; vIAsc.reserve( vpSections.size()) ;
for ( int i = 0 ; i < ssize( vpSections) ; ++ i) {
Point3d ptStart ;
if ( ! vpSections[i]->GetStartPoint( ptStart))
return false ;
vIAsc.emplace_back( i, ptStart.x) ;
}
sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) { return a.second > b.second ; }) ;
ICRVCOMPOPOVECTOR vpSortedSections ; vpSortedSections.reserve( vpSections.size()) ;
for ( int i = 0 ; i < ssize( vIAsc) ; ++ i) {
int nOldPos = vIAsc[i].first ;
vpSortedSections.emplace_back( ::Release( vpSections[nOldPos])) ;
}
swap( vpSortedSections, vpSections) ;
erase_if( vpSections, []( const ICurveComposite* pSection) { return ( pSection == nullptr || ! pSection->IsValid()) ; }) ;
return ( ! vpSections.empty()) ;
}
@@ -2646,28 +2673,72 @@ SawFinishing::Split5ASection( int nSectGrpId, SECTIONVECTOR& vSections) const
nSectId = m_pGeomDB->GetNext( nSectId) ;
}
// elimino eventuali sottosquadra (splittando anche gli archi in sopra/sotto)
// elimino eventuali sottosquadra e oriento ogni curva secondo X descrescente
ICRVCOMPOPOVECTOR vpNucCrvs ; vpNucCrvs.reserve( vpSects.size()) ;
for ( const auto& pSect : vpSects) {
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo) ||
! pCrvCompo->AddCurve( *pSect) ||
! pCrvCompo->RemoveUndercutOnY( LIN_TOL_STD, ANG_TOL_STD_DEG))
! pCrvCompo->RemoveUndercutOnY( LIN_TOL_STD, ANG_TOL_STD_DEG) ||
! vpNucCrvs.emplace_back( Release( pCrvCompo)))
return false ;
vpNucCrvs.emplace_back( Release( pCrvCompo)) ;
Point3d ptS ; vpNucCrvs.back()->GetStartPoint( ptS) ;
Point3d ptE ; vpNucCrvs.back()->GetEndPoint( ptE) ;
if ( ptS.x < ptE.x)
vpNucCrvs.back()->Invert() ;
}
// oriento le sezioni
// le curve ricavate vengo ordinate per X descrescente
// NB. prima le curve sono orientate per X decrescente, quindi ogni curva si muove verso sinistra; ora, se si hanno più sezioni, queste
// vengono lavorate oridinatamente da destra a sinistra
typedef pair<int,double> INDASC ; // coppia indice, ascissa
typedef vector<INDASC> INDASCVECTOR ; // vettore di coppie indice, ascissa
INDASCVECTOR vIAsc ; vIAsc.reserve( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
// se tratto non valido, errore
if ( IsNull( vpNucCrvs[i]) || ! vpNucCrvs[i]->IsValid())
Point3d ptStart ;
if ( ! vpNucCrvs[i]->GetStartPoint( ptStart))
return false ;
vIAsc.emplace_back( i, ptStart.x) ;
}
sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) { return a.second > b.second ; }) ;
ICRVCOMPOPOVECTOR vpSortedSections ; vpSortedSections.reserve( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vIAsc) ; ++ i) {
int nOldPos = vIAsc[i].first ;
vpSortedSections.emplace_back( ::Release( vpNucCrvs[nOldPos])) ;
}
swap( vpSortedSections, vpNucCrvs) ;
// oriento la curva corrente per X decrescenti
Point3d ptStart ; vpNucCrvs[i]->GetStartPoint( ptStart) ;
Point3d ptEnd ; vpNucCrvs[i]->GetEndPoint( ptEnd) ;
if ( ptEnd.x > ptStart.x)
vpNucCrvs[i]->Invert() ;
// calcolo il Box delle sezioni e controllo quali posso unire tra di loro
if ( ssize( vpNucCrvs) > 1) {
const double TOL_STICK_SECTION = m_TParams.m_dThick + 10. * EPS_SMALL ;
BOXVECTOR vBBoxSection( ssize( vpNucCrvs), BBox3d()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
vpNucCrvs[i]->GetLocalBBox( vBBoxSection[i]) ;
vBBoxSection[i].Expand( TOL_STICK_SECTION / 2.) ; // espando per includere la tolleranza
}
// verifico quali sezioni posso unire tra di loro
ICRVCOMPOPOVECTOR vLinkedSection ; vLinkedSection.reserve( vpNucCrvs.size()) ;
vLinkedSection.resize( 1) ;
if ( ! vLinkedSection.back().Set( ConvertCurveToComposite( Release( vpNucCrvs[0]))))
return false ;
for ( int i = 1 ; i < ssize( vpNucCrvs) ; ++ i) {
// controllo se il Box corrente interseca il precedente
if ( vBBoxSection[i-1].OverlapsXY( vBBoxSection[i])) {
Point3d pt ; vpNucCrvs[i]->GetStartPoint( pt) ;
if ( IsNull( vLinkedSection.back()))
return false ;
vLinkedSection.back()->AddLine( pt) ;
vLinkedSection.back()->AddCurve( Release( vpNucCrvs[i])) ;
}
else {
vLinkedSection.resize( vLinkedSection.size() + 1) ;
if ( ! vLinkedSection.back().Set( ConvertCurveToComposite( Release( vpNucCrvs[i]))))
return false ;
}
}
vpNucCrvs.clear() ; vpNucCrvs.resize( vLinkedSection.size()) ;
for ( int i = 0 ; i < ssize( vLinkedSection) ; ++ i)
vpNucCrvs[i].Set( Release( vLinkedSection[i])) ;
}
// dalle sezioni semplici recuperate eseguo l'Offset Radiale complessivo ( evito così interferenze con sezioni differenti)
@@ -2685,26 +2756,6 @@ SawFinishing::Split5ASection( int nSectGrpId, SECTIONVECTOR& vSections) const
}
}
// calcolo ordinamento delle curve secondo la X decrescente
typedef pair<int,double> INDASC ; // coppia indice, ascissa
typedef vector<INDASC> INDASCVECTOR ; // vettore di coppie indice, ascissa
INDASCVECTOR vIAsc ;
vIAsc.reserve( vSections.size()) ;
for ( int i = 0 ; i < ssize( vSections) ; ++ i) {
Point3d ptStart ;
if ( ! vSections[i].pSection->GetStartPoint( ptStart))
return false ;
vIAsc.emplace_back( i, ptStart.x) ;
}
sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) { return a.second > b.second ; }) ;
for ( int nNewPos = 0 ; nNewPos < ssize( vIAsc) ; ++ nNewPos) {
int nOldPos = vIAsc[nNewPos].first ;
if ( nOldPos == nNewPos)
continue ;
swap( vSections[nNewPos], vSections[nOldPos]) ;
swap( vIAsc[nNewPos].first, vIAsc[nOldPos].first) ;
}
// !<-- NB:
// - Una Section semplice non presente tratti verticali e non presenta tratti in sottosquadra
// - Una Section semplice è orientata per X decrescente
@@ -3540,6 +3591,7 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
}
// scorro le sezioni
double dLastElev = 0. ;
for ( int nSect = 0 ; nSect < ssize( vSections) ; ++ nSect) {
// recupero la sezione
@@ -3549,6 +3601,10 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
// scorro le SubSection ottenute
bool bLastToolInv = false ;
bool bFirst = true ;
Point3d ptStartPrev ;
Vector3d vtCorrPrev = V_NULL,
vtToolPrev = V_NULL ;
for ( int nSubSect = 0 ; nSubSect < ssize( Section.vSubSections) ; ++ nSubSect) {
// recupero la SubSection corrente, se non valida, passo alla successiva
@@ -3556,10 +3612,6 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
PtrOwner<ICurveComposite> pSubSect( CloneCurveComposite( SubSection.pSubSection)) ;
if ( pSubSect == nullptr || ! pSubSect->IsValid())
continue ;
// essendo l'utensile inclinato e la testa con orientamento forzato è meglio estendere la sezione per evitare lavorazioni
// a filo dei suoi bordi
pSubSect->ExtendStartByLen( 50. * EPS_SMALL) ;
pSubSect->ExtendEndByLen( 50. * EPS_SMALL) ;
// calcolo della lunghezza dello step e del numero di step complessivi
double dStep = max( m_Params.m_dSideStep, 10. * EPS_SMALL) ;
@@ -3572,10 +3624,6 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
dStep = dLen / nStep ;
// Ciclo sulle passate
double dLastElev ;
Point3d ptStartPrev ;
Vector3d vtCorrPrev = V_NULL,
vtToolPrev = V_NULL ;
for ( int i = 0 ; i <= nStep ; ++ i) {
// coordinate nel punto, del versore correzione e del versore utensile
double dLcurr = i * dStep ;
@@ -3586,31 +3634,24 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
return false ;
Vector3d vtCorr = GetToGlob( vtTan, frSect) ;
vtCorr.Rotate( vtGdDir, m_Params.m_bInvert ? - ANG_RIGHT : ANG_RIGHT) ;
// se tangente circa orizzontale
if ( abs( vtTan.y) < 2. * EPS_SMALL) {
if ( ( SubSection.nHeadSide == SAWFIN_HS_LEFT && vtTan.y < 0.) ||
( SubSection.nHeadSide == SAWFIN_HS_RIGHT && vtTan.y > 0.))
vtTan.y = - vtTan.y ;
// se tangente circa orizzontale, correggo la direzione per evitare inversioni di vtTool
if ( abs( vtTan.y) < 5 * EPS_SMALL) {
if ( ( SubSection.nHeadSide == SAWFIN_HS_LEFT)) {
vtTan.y = abs( vtTan.y) ; // y > 0.
vtTan.x = - abs( vtTan.x) ; // x < 0.
}
else if ( SubSection.nHeadSide == SAWFIN_HS_RIGHT) {
vtTan.y = - abs( vtTan.y) ; // y < 0.
vtTan.x = abs( vtTan.x) ; // x > 0.
}
}
Vector3d vtTool = GetToGlob( vtTan, frSect) ;
// determino l'orientamento della testa
bool bCurrToolInv = false ;
if ( vtTool.z < - EPS_ZERO) {
vtTool.Invert() ; // NB. vtTool deve sempre avere la componente Z come positiva (quindi vtCorr.y >= 0)
bCurrToolInv = true ;
}
// verifico se inversione della testa
bool bFirst = ( i == 0) ;
bool bSpecialAppr = ( m_Params.m_nLeadLinkType != SAWFIN_LL_CENT && ! bFirst && ( bCurrToolInv != bLastToolInv)) ;
if ( bSpecialAppr) {
SetFeed( GetEndFeed()) ;
Point3d ptCurr ; GetCurrPos( ptCurr) ;
if ( ! AddRetract( ptCurr, vtCorrPrev, GetSafeZ(), dLastElev, m_Params.m_dStartPos))
return false ;
}
bLastToolInv = bCurrToolInv ;
// NB. vtTool deve sempre avere la componente Z come positiva (quindi vtCorr.y >= 0)
bool bCurrToolInv = ( SubSection.nHeadSide == SAWFIN_HS_RIGHT) ;
if ( vtTool.z < - 5. * EPS_SMALL)
vtTool.Invert() ;
// punto di passata è sulla metà della sezione lama
ptP += - 0.5 * m_TParams.m_dThick * GetToLoc( vtTool, frSect) ;
@@ -3627,6 +3668,9 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
if ( bOtherColl || bAwayFromPoint)
continue ;
// verifico se inversione della testa
bool bSpecialAppr = ( m_Params.m_nLeadLinkType != SAWFIN_LL_CENT && ! bFirst && ( bCurrToolInv != bLastToolInv)) ;
// definisco gli estremi del tratto rettilineo in globale
Point3d ptPCAvSect = GetToGlob( ptP, frSect) + vtCorr * dSectElev ;
if ( m_Params.m_bInvert)
@@ -3696,11 +3740,11 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
if ( bFirst || ! AreSamePointEpsilon( ptStart, ptStartPrev, 10. * EPS_SMALL)) {
if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) {
if ( ! CalcAlong5AOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtToolPrev, vtCorr, vtCorrPrev, dElev, bExtend, false,
bFirst))
bFirst, bSpecialAppr))
return false ;
}
else {
if ( ! CalcAlong5AZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtToolPrev, vtCorr, vtCorrPrev, dElev, bExtend, false,
if ( ! CalcAlong5AZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtToolPrev, vtCorr, vtCorrPrev, dElev, dLastElev, bExtend, false,
bFirst, bSpecialAppr))
return false ;
}
@@ -3708,20 +3752,24 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
dLastElev = dElev ;
ptStartPrev = ptStart ;
}
bFirst = false ;
vtCorrPrev = vtCorr ;
vtToolPrev = vtTool ;
bLastToolInv = bCurrToolInv ;
}
// se ZigZag e non centrato aggiungo risalita
if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG && m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) {
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
// aggiungo retrazione
Point3d ptNewEnd ;
if ( ! GetCurrPos( ptNewEnd) || ! AddRetract( ptNewEnd, Z_AX, dSafeZ, dLastElev, dAppr))
return false ;
}
}
// se ZigZag e non centrato aggiungo risalita
if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG && m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) {
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
// recupero direzione utensile corrente
Vector3d vtCorr ; GetCurrCorr( vtCorr) ;
// aggiungo retrazione
Point3d ptNewEnd ;
if ( ! GetCurrPos( ptNewEnd) || ! AddRetract( ptNewEnd, vtCorr, dSafeZ, dLastElev, dAppr))
return false ;
}
}
@@ -3732,7 +3780,7 @@ SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& fr
bool
SawFinishing::CalcAlong5AOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool,
const Vector3d& vtToolPrev, const Vector3d& vtCorr, const Vector3d& vtCorrPrev,
double dElev, bool bExtend, bool bVert, bool bFirst)
double dElev, bool bExtend, bool bVert, bool bFirst, bool bAppr)
{
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
@@ -3742,9 +3790,8 @@ SawFinishing::CalcAlong5AOneWayCut( const Point3d& ptStart, const Point3d& ptEnd
// se attacco/uscita/collegamento esterno allungo inizio
Point3d ptNewStart = ptStart ;
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_STD) {
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_STD)
ptNewStart = ptStart - vtDir * dAlongAppr ;
}
else if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
// distanza XY tra centro e bordo taglio
double dDeltaT = 0 ;
@@ -3755,34 +3802,46 @@ SawFinishing::CalcAlong5AOneWayCut( const Point3d& ptStart, const Point3d& ptEnd
}
// 1 -> approccio
// verifico se la deviazione angolare tra la passata corrente ela precedente superla la tolleranza
// effettuo una retroazione se :
// - ho un approccio forzato dovuto all'inversione dell'utensile
// - la deviazione angolare tra la passata corrente e la precedente supera la tolleranza
const double ANG_DEG_MAX = 10. ;
if ( ! bFirst && vtToolPrev.IsValid() && vtTool.IsValid() && vtTool * vtToolPrev < cos( ANG_DEG_MAX * DEGTORAD)) {
// Tengo l'utensile orientato come la passata precedente
SetToolDir( vtToolPrev) ;
SetCorrDir( vtCorrPrev) ;
// Recupero il punto corrente e il nuovo punto di destinazione al du fuori del grezzo
Point3d ptCurr ; GetCurrPos( ptCurr) ;
// Se link di tipo out, aggiungo la retroazione al percorso precedente
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
if ( ! AddRetract( ptCurr, vtCorr, dSafeZ, dElev, dAppr))
return false ;
if ( ! bFirst && vtToolPrev.IsValid() && vtTool.IsValid()) {
// se approccio forzato per inversione utensile
if ( bAppr || vtTool * vtToolPrev < cos( ANG_DEG_MAX * DEGTORAD)) {
// Recupero il punto corrente
Point3d ptCurr ; GetCurrPos( ptCurr) ;
// Recupero il punto di approccio per il nuovo collegamento
double dMyAppr = max( dAppr, 1.0) ;
Point3d ptAppr ;
if ( dSafeZ < dMyAppr + 10 * EPS_SMALL)
ptAppr = ptNewStart + vtCorr * dElev ;
else
ptAppr = ptNewStart + vtCorr * ( dElev + dSafeZ) ;
// aggiungo il movimento in rapido per il collegamento speciale al di fuori del grezzo
double dDeltaZ = ptAppr.z - ptCurr.z ;
// se discesa
if ( dDeltaZ < 0.) {
Point3d ptA = ptAppr + Z_AX * ( - dDeltaZ) ;
if ( ! SameAsCurrPos( ptA)) {
if ( AddRapidMove( ptA) == GDB_ID_NULL)
return false ;
}
}
// se salita
else {
Point3d ptA = ptCurr + Z_AX * dDeltaZ ;
if ( ! SameAsCurrPos( ptA)) {
if ( AddRapidMove( ptA) == GDB_ID_NULL)
return false ;
}
}
// Approccio al nuovo punto
if ( ! SameAsCurrPos( ptAppr)) {
if ( AddRapidMove( ptAppr) == GDB_ID_NULL)
return false ;
}
}
// Recupero la Z del punto di destinazione
double dMyAppr = max( dAppr, 1.0) ;
Point3d ptAppr ;
if ( dSafeZ < dMyAppr + 10 * EPS_SMALL)
ptAppr = ptNewStart + vtCorr * dElev ;
else
ptAppr = ptNewStart + vtCorr * ( dElev + dSafeZ) ;
// aggiungo il movimento in rapido per il collegamento speciale al di fuori del grezzo
double dDeltaZ = ptAppr.z - ptCurr.z ; // se scendo < 0, se salgo > 0
if ( dDeltaZ < 0)
AddRapidMove( ptAppr + Z_AX * ( - dDeltaZ)) ;
else
AddRapidMove( ptCurr + Z_AX * dDeltaZ) ;
SetToolDir( vtTool) ;
SetCorrDir( vtCorr) ;
}
if ( ! AddApproach( ptNewStart, vtCorr, dSafeZ, dElev, dAppr))
return false ;
@@ -3811,7 +3870,7 @@ SawFinishing::CalcAlong5AOneWayCut( const Point3d& ptStart, const Point3d& ptEnd
bool
SawFinishing::CalcAlong5AZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool,
const Vector3d& vtToolPrev, const Vector3d& vtCorr, const Vector3d& vtCorrPrev, double dElev,
bool bExtend, bool bVert, bool bFirst, bool bAppr)
double dLastElev, bool bExtend, bool bVert, bool bFirst, bool bAppr)
{
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
@@ -3825,14 +3884,14 @@ SawFinishing::CalcAlong5AZigZagCut( const Point3d& ptStart, const Point3d& ptEnd
Point3d ptNewStart = ptStart ;
Point3d ptNewEnd = ptEnd ;
Vector3d vtNewDir = vtDir ;
// se attacco/uscita/collegamento standard allungo inizio e fine dell'approccio
// se attacco/uscita/collegamento standard allungo inizio e fine dell'approccio
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_STD) {
// modifico inizio
ptNewStart = ptStart - vtDir * dAlongAppr ;
// modifico fine
ptNewEnd = ptEnd + vtDir * dAlongAppr ;
}
// se attacco/uscita/collegamento esterno allungo inizio e fine a fuori grezzo
// se attacco/uscita/collegamento esterno allungo inizio e fine a fuori grezzo
else if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
// distanza XY tra centro e bordo taglio
double dDeltaT = 0 ;
@@ -3851,39 +3910,111 @@ SawFinishing::CalcAlong5AZigZagCut( const Point3d& ptStart, const Point3d& ptEnd
}
// 1 -> approccio
// Verifico se la deviazione angolare tra la passata corrente e la precedente supera la tolleranza
// effettuo una retroazione se :
// - ho un approccio forzato dovuto all'inversione dell'utensile
// - la deviazione angolare tra la passata corrente e la precedente supera la tolleranza
const double ANG_DEG_MAX = 10. ;
bool bOutRaw = false ;
if ( ! bFirst && vtToolPrev.IsValid() && vtTool.IsValid() && vtTool * vtToolPrev < cos( ANG_DEG_MAX * DEGTORAD)) {
// Tengo l'utensile orientato come la passata precedente
SetToolDir( vtToolPrev) ;
SetCorrDir( vtCorrPrev) ;
// Recupero il punto corrente e il nuovo punto di destinazione al du fuori del grezzo
Point3d ptCurr ; GetCurrPos( ptCurr) ;
// Se link di tipo out, aggiungo la retroazione al percorso precedente
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
if ( ! AddRetract( ptCurr, vtCorr, dSafeZ, dElev, dAppr))
return false ;
bool bPrevRetract = false ;
if ( ! bFirst && vtToolPrev.IsValid() && vtTool.IsValid()) {
// se approccio forzato per inversione utensile
if ( bAppr) {
// recupero il punto corrente
Point3d ptCurr ; GetCurrPos( ptCurr) ;
// tengo l'utensile orientato come la passata precedente
SetToolDir( vtToolPrev) ;
SetCorrDir( vtCorrPrev) ;
// Aggiungo la retroazione (se link centrati è già aggiunta)
if ( m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) {
if ( ! AddRetract( ptCurr, vtCorrPrev, dSafeZ, dLastElev, dAppr))
return false ;
GetCurrPos( ptCurr) ;
}
// Recupero il punto di approccio per il nuovo collegamento
double dMyAppr = max( dAppr, 1.0) ;
Point3d ptAppr ;
if ( dSafeZ < dMyAppr + 10 * EPS_SMALL)
ptAppr = ptNewStart + vtCorr * dElev ;
else
ptAppr = ptNewStart + vtCorr * ( dElev + dSafeZ) ;
// imposto i dati utensili nuovi
SetToolDir( vtTool) ;
SetCorrDir( vtCorr) ;
// aggiungo il movimento in rapido per il collegamento speciale al di fuori del grezzo
double dDeltaZ = ptAppr.z - ptCurr.z ;
// se discesa
if ( dDeltaZ < 0.) {
Point3d ptA = ptAppr + Z_AX * ( - dDeltaZ) ;
if ( ! SameAsCurrPos( ptA)) {
if ( AddRapidMove( ptA) == GDB_ID_NULL)
return false ;
}
}
// se salita
else {
Point3d ptA = ptCurr + Z_AX * dDeltaZ ;
if ( ! SameAsCurrPos( ptA)) {
if ( AddRapidMove( ptA) == GDB_ID_NULL)
return false ;
}
}
// Approccio al nuovo punto
if ( ! SameAsCurrPos( ptAppr)) {
if ( AddRapidMove( ptAppr) == GDB_ID_NULL)
return false ;
}
bPrevRetract = true ;
}
// se la deviazione angolare supera la tolleranza
else if ( vtTool * vtToolPrev < cos( ANG_DEG_MAX * DEGTORAD)) {
// Recupero il punto corrente
Point3d ptCurr ; GetCurrPos( ptCurr) ;
// Tengo l'utensile orientato come la passata precedente
SetToolDir( vtToolPrev) ;
SetCorrDir( vtCorrPrev) ;
// Aggiungo la retroazione (se link centrati è già aggiunta)
if ( m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) {
if ( ! AddRetract( ptCurr, vtCorrPrev, dSafeZ, dLastElev, dAppr))
return false ;
GetCurrPos( ptCurr) ;
}
// Recupero il punto di approccio per il nuovo collegamento
double dMyAppr = max( dAppr, 1.0) ;
Point3d ptAppr ;
if ( dSafeZ < dMyAppr + 10 * EPS_SMALL)
ptAppr = ptNewStart + vtCorr * dElev ;
else
ptAppr = ptNewStart + vtCorr * ( dElev + dSafeZ) ;
// aggiungo il movimento in rapido per il collegamento speciale al di fuori del grezzo
double dDeltaZ = ptAppr.z - ptCurr.z ;
// se discesa
if ( dDeltaZ < 0.) {
Point3d ptA = ptAppr + Z_AX * ( - dDeltaZ) ;
if ( ! SameAsCurrPos( ptA)) {
if ( AddRapidMove( ptA) == GDB_ID_NULL)
return false ;
}
}
// se salita
else {
Point3d ptA = ptCurr + Z_AX * dDeltaZ ;
if ( ! SameAsCurrPos( ptA)) {
if ( AddRapidMove( ptA) == GDB_ID_NULL)
return false ;
}
}
// imposto i dati utensili nuovi
SetToolDir( vtTool) ;
SetCorrDir( vtCorr) ;
// Approccio al nuovo punto
if ( ! SameAsCurrPos( ptAppr)) {
if ( AddRapidMove( ptAppr) == GDB_ID_NULL)
return false ;
}
bPrevRetract = true ;
}
// Recupero la Z del punto di destinazione
double dMyAppr = max( dAppr, 1.0) ;
Point3d ptAppr ;
if ( dSafeZ < dMyAppr + 10 * EPS_SMALL)
ptAppr = ptNewStart + vtCorr * dElev ;
else
ptAppr = ptNewStart + vtCorr * ( dElev + dSafeZ) ;
// aggiungo il movimento in rapido per il collegamento speciale al di fuori del grezzo
double dDeltaZ = ptAppr.z - ptCurr.z ; // se scendo < 0, se salgo > 0
if ( dDeltaZ < 0)
AddRapidMove( ptAppr + Z_AX * ( - dDeltaZ)) ;
else
AddRapidMove( ptCurr + Z_AX * dDeltaZ) ;
bOutRaw = true ;
SetToolDir( vtTool) ;
SetCorrDir( vtCorr) ;
}
if ( bFirst || m_Params.m_nLeadLinkType == SAWFIN_LL_CENT || bAppr || bOutRaw) {
if ( bFirst || m_Params.m_nLeadLinkType == SAWFIN_LL_CENT || bPrevRetract) {
if ( ! AddApproach( ptNewStart, vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
+2 -2
View File
@@ -130,10 +130,10 @@ class SawFinishing : public Machining
const BBox3d& b3Raw, const ISurfTriMesh* pStmRaw) ;
bool CalcAlong5AOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool,
const Vector3d& vtToolPrev, const Vector3d& vtCorr, const Vector3d& vtCorrPrev, double dElev,
bool bExtend, bool bVert, bool bFirst) ;
bool bExtend, bool bVert, bool bFirst, bool bAppr) ;
bool CalcAlong5AZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool,
const Vector3d& vtToolPrev, const Vector3d& vtCorr, const Vector3d& vtCorrPrev, double dElev,
bool bExtend, bool bVert, bool bFirst, bool bAppr) ;
double dLastElev, bool bExtend, bool bVert, bool bFirst, bool bAppr) ;
bool CalcAlongOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir,
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bExtend, bool bVert) ;
bool CalcAlongZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool,
+56 -21
View File
@@ -1532,6 +1532,8 @@ SawRoughing::CalculateCurvedToolPath( int nAuxId, int nClId)
bool
SawRoughing::CalculateSection( int nSectGrpId, ICRVCOMPOPOVECTOR& vpSections) const
{
vpSections.clear() ;
// recupero le sezioni
ICURVEPVECTOR vpSects ;
int nSectId = m_pGeomDB->GetFirstInGroup( nSectGrpId) ;
@@ -1560,6 +1562,59 @@ SawRoughing::CalculateSection( int nSectGrpId, ICRVCOMPOPOVECTOR& vpSections) co
vpNucCrvs.back()->Invert() ;
}
// le curve ricavate vengo ordinate per X descrescente
// NB. prima le curve sono orientate per X decrescente, quindi ogni curva si muove verso sinistra; ora, se si hanno più sezioni, queste
// vengono lavorate oridinatamente da destra a sinistra
typedef pair<int,double> INDASC ; // coppia indice, ascissa
typedef vector<INDASC> INDASCVECTOR ; // vettore di coppie indice, ascissa
INDASCVECTOR vIAsc ; vIAsc.reserve( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
Point3d ptStart ;
if ( ! vpNucCrvs[i]->GetStartPoint( ptStart))
return false ;
vIAsc.emplace_back( i, ptStart.x) ;
}
sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) { return a.second > b.second ; }) ;
ICURVEPOVECTOR vpSortedSections ; vpSortedSections.reserve( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vIAsc) ; ++ i) {
int nOldPos = vIAsc[i].first ;
vpSortedSections.emplace_back( ::Release( vpNucCrvs[nOldPos])) ;
}
swap( vpSortedSections, vpNucCrvs) ;
// calcolo il Box delle sezioni e controllo quali posso unire tra di loro
if ( ssize( vpNucCrvs) > 1) {
const double TOL_STICK_SECTION = m_TParams.m_dThick + 10. * EPS_SMALL ;
BOXVECTOR vBBoxSection( ssize( vpNucCrvs), BBox3d()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
vpNucCrvs[i]->GetLocalBBox( vBBoxSection[i]) ;
vBBoxSection[i].Expand( TOL_STICK_SECTION / 2.) ; // espando per includere la tolleranza
}
// verifico quali sezioni posso unire tra di loro
ICRVCOMPOPOVECTOR vLinkedSection ; vLinkedSection.reserve( vpNucCrvs.size()) ;
vLinkedSection.resize( 1) ;
if ( ! vLinkedSection.back().Set( ConvertCurveToComposite( ::Release( vpNucCrvs[0]))))
return false ;
for ( int i = 1 ; i < ssize( vpNucCrvs) ; ++ i) {
// controllo se il Box corrente interseca il precedente
if ( vBBoxSection[i-1].OverlapsXY( vBBoxSection[i])) {
Point3d pt ; vpNucCrvs[i]->GetStartPoint( pt) ;
if ( IsNull( vLinkedSection.back()))
return false ;
vLinkedSection.back()->AddLine( pt) ;
vLinkedSection.back()->AddCurve( ::Release( vpNucCrvs[i])) ;
}
else {
vLinkedSection.resize( vLinkedSection.size() + 1) ;
if ( ! vLinkedSection.back().Set( ConvertCurveToComposite( ::Release( vpNucCrvs[i]))))
return false ;
}
}
vpNucCrvs.clear() ; vpNucCrvs.resize( vLinkedSection.size()) ;
for ( int i = 0 ; i < ssize( vLinkedSection) ; ++ i)
vpNucCrvs[i].Set( ::Release( vLinkedSection[i])) ;
}
// dalle sezioni recuperate eseguo l'Offset Radiale complessivo (evito così interferenze con sezioni differenti)
ICURVEPVECTOR vpMySections ; vpMySections.resize( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i)
@@ -1574,7 +1629,7 @@ SawRoughing::CalculateSection( int nSectGrpId, ICRVCOMPOPOVECTOR& vpSections) co
if ( ! vpSections.back().Set( CreateCurveComposite()) ||
! vpSections.back()->AddCurve( vMySections[i]->Clone()))
return false ;
// eseguo anche Offset lungo X
// eseguo Offset lungo X
OffsetCurveOnX OffsCrvX ;
if ( ! OffsCrvX.Make( vpSections.back(), 0.5 * m_TParams.m_dThick + GetOffsL() - GetOffsR()))
return false ;
@@ -1591,26 +1646,6 @@ SawRoughing::CalculateSection( int nSectGrpId, ICRVCOMPOPOVECTOR& vpSections) co
}
}
// le curve ricavate vengo ordinate per X descrescente
// NB. prima le curve sono orientate per X decrescente, quindi ogni curva si muove verso sinistra; ora, se si hanno più sezioni, queste
// vengono lavorate oridinatamente da destra a sinistra
typedef pair<int,double> INDASC ; // coppia indice, ascissa
typedef vector<INDASC> INDASCVECTOR ; // vettore di coppie indice, ascissa
INDASCVECTOR vIAsc ; vIAsc.reserve( vpSections.size()) ;
for ( int i = 0 ; i < ssize( vpSections) ; ++ i) {
Point3d ptStart ;
if ( ! vpSections[i]->GetStartPoint( ptStart))
return false ;
vIAsc.emplace_back( i, ptStart.x) ;
}
sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) { return a.second > b.second ; }) ;
ICRVCOMPOPOVECTOR vpSortedSections ; vpSortedSections.reserve( vpSections.size()) ;
for ( int i = 0 ; i < ssize( vIAsc) ; ++ i) {
int nOldPos = vIAsc[i].first ;
vpSortedSections.emplace_back( ::Release( vpSections[nOldPos])) ;
}
swap( vpSortedSections, vpSections) ;
erase_if( vpSections, []( const ICurveComposite* pSection) { return ( pSection == nullptr || ! pSection->IsValid()) ; }) ;
return ( ! vpSections.empty()) ;
}