EgtMachKernel :

- in SawRoughing modifica per Link esterni
- in SawRoughing aggiunto controllo elevazioni per inizio/fine percorsi
- in SawRoughing rimozione lavorazione a ZConst
- in SawRoughing modificata l'estensione dei link non più al Box3d del grezzo ma alla alla sua superficie.
This commit is contained in:
Riccardo Elitropi
2026-07-03 12:27:25 +02:00
parent 6b3c403f9f
commit 37d649b3a8
2 changed files with 234 additions and 479 deletions
+231 -472
View File
@@ -60,6 +60,7 @@ using namespace std ;
// 2652 = "Warning in SawRoughing : No machinable path"
// 2653 = "Warning in SawRoughing : Tool name changed (xx)"
// 2654 = "Warning in SawRoughing : Tool data changed (xx)"
// 2655 = "Warning in SawRoughing : Link not compatible with extension"
//----------------------------------------------------------------------------
const string MCH_SECTION = "Sect" ;
@@ -1093,6 +1094,11 @@ SawRoughing::CalculateToolPath( int nAuxId, int nPvId, int nClId)
bool bExtend ;
if ( ! GetValInNotes( m_Params.m_sUserNotes, UN_EXTEND, bExtend))
bExtend = true ;
// se estensione non presente e Link di tipoi Extended, lo forzo come Center
if ( ! bExtend && m_Params.m_nLeadLinkType == SAWROU_LL_OUT) {
m_pMchMgr->SetWarning( 2655, "Warning in SawRoughing : Link not compatible with extension") ;
m_Params.m_nLeadLinkType = SAWROU_LL_CENT ;
}
// Recupero ed elaboro la linea guida
Point3d ptGdStart, ptGdEnd ;
@@ -1226,7 +1232,7 @@ SawRoughing::CalculateToolPath( int nAuxId, int nPvId, int nClId)
if ( abs( ptEnd.x - ptStart.x) < EPS_SMALL) {
vdVr.push_back( ( ptEnd.x + ptStart.x) / 2) ;
vdVrDelta.push_back( ptEnd.y - ptStart.y) ;
}
}
}
// Determino le posizioni particolari
@@ -1272,82 +1278,56 @@ SawRoughing::CalculateToolPath( int nAuxId, int nPvId, int nClId)
for ( int j = 1 ; j < int( vdPp.size()) ; ++ j) {
double dXmax = vdPp[j-1] ;
double dXmin = vdPp[j] ;
if ( m_Params.m_nStepType == SAWROU_ST_ZCONST) {
// le pareti verticali vanno trattate nell'intervallo della quota più bassa
bool bIncludeMax = ( vdPDelta[j-1] < EPS_SMALL) ;
bool bIncludeMin = ( vdPDelta[j] > - EPS_SMALL) ;
// verifico se devo trattare l'estremo a dXmax singolarmente
if ( j == 1 && ! bIncludeMax) {
if ( ! CalculateZConstCut( pCrv, dXmax, dXmax, true, false, ptGdStart, ptGdEnd, vtGdDir, frSect, pStmRaw, b3Raw, bExtend, dMaxDepth,
true, false, nCount))
return false ;
}
// tratto l'intervallo
bool bFirstInterval = ( j == 1) && bIncludeMax ;
bool bLastInterval = ( j == vdPp.size() - 1) && bIncludeMin ;
if ( ! CalculateZConstCut( pCrv, dXmin, dXmax, bIncludeMax, bIncludeMin, ptGdStart, ptGdEnd, vtGdDir, frSect, pStmRaw, b3Raw, bExtend, dMaxDepth,
bFirstInterval, bLastInterval, nCount))
return false ;
// verifico se devo trattare l'estremo a dXmin singolarmente
if ( j == vdPp.size() - 1 && ! bIncludeMin) {
if ( ! CalculateZConstCut( pCrv, dXmin, dXmin, false, true, ptGdStart, ptGdEnd, vtGdDir, frSect, pStmRaw, b3Raw, bExtend, dMaxDepth,
false, true, nCount))
return false ;
}
}
else {
double dLargh = dXmax - dXmin ;
double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ;
int nStep = max( 1, static_cast<int>( ceil( dLargh / dStep))) ;
dStep = dLargh / nStep ;
double dSectYMin = b3Crv.GetMin().y ;
double dSectYMax = b3Crv.GetMax().y ;
double dLargh = dXmax - dXmin ;
double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ;
int nStep = max( 1, static_cast<int>( ceil( dLargh / dStep))) ;
dStep = dLargh / nStep ;
double dSectYMin = b3Crv.GetMin().y ;
double dSectYMax = b3Crv.GetMax().y ;
int nStart = ( j == 1 ? 0 : 1) ;
for ( int i = nStart ; i <= nStep ; ++ i) {
// flag per primo e ultimo taglio
bool bFirst = ( j == 1 && i == 0) ;
bool bLast = ( j == vdPp.size() - 1 && i == nStep) ;
// determino l'ascissa della prima intersezione
double dX = dXmax - i * dStep ;
// determino l'ordinata della prima intersezione
double dY ;
if ( ! GetHeightOnSection( pCrv, dX, dSectYMin, dSectYMax, dY))
int nStart = ( j == 1 ? 0 : 1) ;
for ( int i = nStart ; i <= nStep ; ++ i) {
// flag per primo e ultimo taglio
bool bFirst = ( j == 1 && i == 0) ;
bool bLast = ( j == vdPp.size() - 1 && i == nStep) ;
// determino l'ascissa della prima intersezione
double dX = dXmax - i * dStep ;
// determino l'ordinata della prima intersezione
double dY ;
if ( ! GetHeightOnSection( pCrv, dX, dSectYMin, dSectYMax, dY))
return false ;
// estremi del taglio
Vector3d vtMove = dX * frSect.VersX() + dY * frSect.VersY() - 0.5 * m_TParams.m_dThick * vtTool ;
Point3d ptStart = ptGdStart + vtMove ;
Point3d ptEnd = ptGdEnd + vtMove ;
// adatto la guida corrente al grezzo
AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw) ;
// determino l'elevazione del taglio
Vector3d vtThick = vtTool * m_TParams.m_dThick ;
double dElev, dElev2 ;
if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) ||
! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) {
m_pMchMgr->SetLastError( 2609, "Error in SawRoughing : GetElevation") ;
return false ;
}
dElev = max( dElev, dElev2) ;
// se elevazione nulla, verifico col massimo del grezzo
if ( dElev < EPS_SMALL)
dElev = max( 0., b3Raw.GetMax().z - ptStart.z) ;
// la confronto con il massimo affondamento e con la massima lavorazione della lama
if ( dElev > dMaxDepth) {
ptStart += Vector3d( 0, 0, dElev - dMaxDepth) ;
ptEnd += Vector3d( 0, 0, dElev - dMaxDepth) ;
dElev = dMaxDepth ;
}
// esecuzione del taglio
if ( m_Params.m_nStepType != SAWROU_ST_ZIGZAG) {
if ( ! CalculateOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, pStmRaw))
return false ;
// estremi del taglio
Vector3d vtMove = dX * frSect.VersX() + dY * frSect.VersY() - 0.5 * m_TParams.m_dThick * vtTool ;
Point3d ptStart = ptGdStart + vtMove ;
Point3d ptEnd = ptGdEnd + vtMove ;
// adatto la guida corrente al grezzo
AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw) ;
// determino l'elevazione del taglio
Vector3d vtThick = vtTool * m_TParams.m_dThick ;
double dElev, dElev2 ;
if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) ||
! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) {
m_pMchMgr->SetLastError( 2609, "Error in SawRoughing : GetElevation") ;
}
else {
if ( ! CalculateZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, nCount, pStmRaw))
return false ;
}
dElev = max( dElev, dElev2) ;
// se elevazione nulla, verifico col massimo del grezzo
if ( dElev < EPS_SMALL)
dElev = max( 0., b3Raw.GetMax().z - ptStart.z) ;
// la confronto con il massimo affondamento e con la massima lavorazione della lama
if ( dElev > dMaxDepth) {
ptStart += Vector3d( 0, 0, dElev - dMaxDepth) ;
ptEnd += Vector3d( 0, 0, dElev - dMaxDepth) ;
dElev = dMaxDepth ;
}
// esecuzione del taglio
if ( m_Params.m_nStepType != SAWROU_ST_ZIGZAG) {
if ( ! CalculateOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, b3Raw))
return false ;
}
else {
if ( ! CalculateZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, nCount, b3Raw))
return false ;
}
}
}
}
@@ -1781,7 +1761,7 @@ SawRoughing::AdaptGuideLineToRaw( Point3d& ptGdStart, Point3d& ptGdEnd, const Ve
//----------------------------------------------------------------------------
bool
SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir,
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, const BBox3d& b3Raw)
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, const ISurfTriMesh* pStmRaw)
{
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
@@ -1793,13 +1773,10 @@ SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, c
if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) {
// distanza XY tra centro e bordo taglio
double dDeltaT = 0 ;
if ( dElev > 0.0 && dElev < 0.5 * m_TParams.m_dDiam)
dDeltaT = sqrt( dElev * m_TParams.m_dDiam - dElev * dElev) ;
// correzione per guida inclinata
Vector3d vtRef = Y_AX ;
if ( abs( ptStart.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptStart.y - b3Raw.GetMax().y) < EPS_SMALL)
vtRef = X_AX ;
dDeltaT += m_TParams.m_dThick * ( vtDir * vtRef) / ( vtDir ^ vtRef).Len() ;
if ( pStmRaw != nullptr) {
if ( ! GetElevation( m_nPhase, ptStart, vtTool, m_TParams.m_dDiam /2., m_TParams.m_dLen, dSafeZ, - vtDir, dDeltaT))
return false ;
}
// modifico inizio
ptNewStart = ptStart - vtDir * ( dDeltaT + dAppr) ;
}
@@ -1867,7 +1844,7 @@ SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, c
if ( AddLinearMove( ptP5) == GDB_ID_NULL)
return false ;
}
}
}
// 4 -> retrazione
if ( ! AddRetract( ptEnd, vtCorr, dSafeZ, dElev, dAppr))
return false ;
@@ -1880,7 +1857,7 @@ SawRoughing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, c
bool
SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir,
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast,
int& nCount, const BBox3d& b3Raw)
int& nCount, const ISurfTriMesh* pStmRaw)
{
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
@@ -1895,29 +1872,17 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c
Vector3d vtNewDir = vtDir ;
// se attacco/uscita/collegamento esterno allungo inizio e fine
if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) {
// distanza XY tra centro e bordo taglio
double dDeltaT = 0 ;
if ( dElev > 0.0 && dElev < 0.5 * m_TParams.m_dDiam)
dDeltaT = sqrt( dElev * m_TParams.m_dDiam - dElev * dElev) ;
double dDeltaTSt = dDeltaT ;
double dDeltaTEn = dDeltaT ;
// calcolo correzione per guida inclinata per far fuoriuscire la lama di tutto lo spessore
// ricavo il lato di uscita dal grezzo dello start
Vector3d vtRef = Y_AX ;
if ( abs( ptStart.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptStart.y - b3Raw.GetMax().y) < EPS_SMALL)
vtRef = X_AX ;
dDeltaTSt += m_TParams.m_dThick * ( vtDir * vtRef) / ( vtDir ^ vtRef).Len() ;
// end
vtRef = Y_AX ;
if ( abs( ptEnd.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptEnd.y - b3Raw.GetMax().y) < EPS_SMALL)
vtRef = X_AX ;
dDeltaTEn += m_TParams.m_dThick * ( vtDir * vtRef) / ( vtDir ^ vtRef).Len() ;
double dDeltaTSt = 0., dDeltaTEn = 0. ;
if ( pStmRaw != nullptr) {
if ( ! GetElevation( m_nPhase, ptStart, vtTool, m_TParams.m_dDiam / 2., m_TParams.m_dLen, dSafeZ, - vtDir, dDeltaTSt) ||
! GetElevation( m_nPhase, ptEnd, vtTool, m_TParams.m_dDiam / 2., m_TParams.m_dLen, dSafeZ, vtDir, dDeltaTEn))
return false ;
}
// modifico inizio
ptNewStart = ptStart - vtDir * ( dDeltaTSt + dAppr) ;
// modifico fine
ptNewEnd = ptEnd + vtDir * ( dDeltaTEn + dAppr) ;
}
}
// le passate dispari sono al contrario
if ( ( nCount % 2) != 0) {
swap( ptOriStart, ptOriEnd) ;
@@ -1934,7 +1899,7 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c
}
// 2 -> movimento in affondo al punto iniziale
SetFlag( 0) ;
// con attacco centrato sono sul materiale e devo usare feed di testa
// con attacco centrato sono sul materiale e devo usare feed di testa
if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) {
SetFeed( GetTipFeed()) ;
Point3d ptCurr ; GetCurrPos( ptCurr) ;
@@ -1943,44 +1908,108 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c
return false ;
}
}
// con attacco fuori sono in aria
// con attacco fuori
else {
// se primo movimento
if ( bFirst) {
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart) == GDB_ID_NULL)
return false ;
}
// altrimenti
else {
Point3d ptLast ;
GetCurrPos( ptLast) ;
Point3d ptLast ; GetCurrPos( ptLast) ;
double dDiff = ( ptNewStart - ptLast) * vtNewDir ;
// se precedente e corrente sono fuori allo stesso modo
if ( abs( dDiff) < 10 * EPS_SMALL) {
// inizio nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart) == GDB_ID_NULL)
return false ;
// se precedente e corrente sono fuori allo stesso modo, inizio nuova passata
if ( abs( dDiff) < 10. * EPS_SMALL) {
// controllo se mi trovo dentro o fuori dal grezzo
double dElev = 0. ;
if ( GetElevation( m_nPhase, ptLast, ptNewStart, m_vtCorr, dElev) && dElev < EPS_SMALL) {
// fuori dal grezzo
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart) == GDB_ID_NULL)
return false ;
}
else {
// dentro al grezzo
// -> movimento di risalita
SetFeed( GetEndFeed()) ;
Point3d ptAbove = ptLast + m_vtCorr * ( dElev + dSafeZ) ;
if ( AddLinearMove( ptAbove) == GDB_ID_NULL)
return false ;
// -> allineamento fuori dal grezzo
Vector3d vtDir = OrthoCompo( ( ptNewStart - ptAbove), m_vtCorr) ;
if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL)
return false ;
// -> discesa al nuovo punto iniziale
SetFeed( GetTipFeed()) ;
if ( AddLinearMove( ptNewStart) == GDB_ID_NULL)
return false ;
}
}
// se il precedente è più fuori
else if ( dDiff > 0) {
else if ( dDiff > 0.) {
// allungo nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart - dDiff * vtNewDir) == GDB_ID_NULL)
return false ;
Point3d ptDest = ptNewStart - dDiff * vtNewDir ;
// controllo se mi trovo dentro o fuori dal grezzo
double dElev = 0. ;
if ( GetElevation( m_nPhase, ptLast, ptDest, m_vtCorr, dElev) && dElev < EPS_SMALL) {
// fuori dal grezzo
if ( AddLinearMove( ptDest) == GDB_ID_NULL)
return false ;
}
else {
// dentro al grezzo
// -> movimento di risaluta
SetFeed( GetEndFeed()) ;
Point3d ptAbove = ptLast + m_vtCorr * ( dElev + dSafeZ) ;
if ( AddLinearMove( ptAbove) == GDB_ID_NULL)
return false ;
// -> allineamento sopra al grezzo
Vector3d vtDir = OrthoCompo( ( ptDest - ptAbove), m_vtCorr) ;
if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL)
return false ;
// -> discesa al nuovo punto iniziale
SetFeed( GetTipFeed()) ;
if ( AddLinearMove( ptDest) == GDB_ID_NULL)
return false ;
}
}
// se il corrente è più fuori
else {
// allungo passata precedente
if ( AddLinearMove( ptLast + dDiff * vtNewDir) == GDB_ID_NULL)
return false ;
// inizio nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart) == GDB_ID_NULL)
Point3d ptExtend = ptLast + dDiff * vtNewDir ;
if ( AddLinearMove( ptExtend) == GDB_ID_NULL)
return false ;
// inizio nuova passata, controllo se mi trovo fuori dal grezzo
double dElev = 0. ;
if ( GetElevation( m_nPhase, ptExtend, ptNewStart, m_vtCorr, dElev) && dElev < EPS_SMALL) {
// fuori dal grezzo
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart) == GDB_ID_NULL)
return false ;
}
else {
// dentro la grezzo
// -> movimento di risalita
SetFeed( GetEndFeed()) ;
Point3d ptAbove = ptExtend + m_vtCorr * ( dElev + dSafeZ) ;
if ( AddLinearMove( ptAbove) == GDB_ID_NULL)
return false ;
// -> allineamento fuori dal grezzo
Vector3d vtDir = OrthoCompo( ( ptNewStart - ptAbove), m_vtCorr) ;
if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL)
return false ;
// -> discesa al nuovo punto iniziale
SetFeed( GetTipFeed()) ;
if ( AddLinearMove( ptNewStart) == GDB_ID_NULL)
return false ;
}
}
}
}
// 3 -> movimento di lato al punto finale
// 3 -> movimento al punto finale
if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) {
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewEnd) == GDB_ID_NULL)
@@ -2036,32 +2065,95 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c
return false ;
}
else {
Point3d ptLast ;
GetCurrPos( ptLast) ;
Point3d ptLast ; GetCurrPos( ptLast) ;
double dDiff = ( ptNewStart - ptLast) * vtNewDir ;
// se precedente e corrente sono fuori allo stesso modo
if ( abs( dDiff) < 10 * EPS_SMALL) {
// inizio nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart + vtCorr * dDelta) == GDB_ID_NULL)
return false ;
// se precedente e corrente sono fuori allo stesso modo, inizio nulva passata
if ( abs( dDiff) < 10. * EPS_SMALL) {
Point3d ptDest = ptNewStart + vtCorr * dDelta ;
// controllo se mi trovo dentro o fuori dal grezzo
double dElev = 0. ;
if ( GetElevation( m_nPhase, ptLast, ptDest, m_vtCorr, dElev) && dElev < EPS_SMALL) {
// fuori dal grezzo
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptDest) == GDB_ID_NULL)
return false ;
}
else {
// dentro al grezzo
// -> movimento di risalita
SetFeed( GetEndFeed()) ;
Point3d ptAbove = ptLast + m_vtCorr * ( dElev + dSafeZ) ;
if ( AddLinearMove( ptAbove) == GDB_ID_NULL)
return false ;
// -> allinamento fuori dal grezzo
Vector3d vtDir = OrthoCompo( ( ptDest - ptAbove), m_vtCorr) ;
if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL)
return false ;
// -> disscesa al nuovo punto iniziale
SetFeed( GetTipFeed()) ;
if ( AddLinearMove( ptDest) == GDB_ID_NULL)
return false ;
}
}
// se il precedente è più fuori
else if ( dDiff > 0) {
else if ( dDiff > 0.) {
// allungo nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart + vtCorr * dDelta - dDiff * vtNewDir) == GDB_ID_NULL)
return false ;
Point3d ptDest = ptNewStart + vtCorr * dDelta - dDiff * vtNewDir ;
// controllo se mi trovo dentro o fuori dal grezzo
if ( GetElevation( m_nPhase, ptLast, ptDest, m_vtCorr, dElev) && dElev < EPS_SMALL) {
// fuori dal grezzo
if ( AddLinearMove( ptDest) == GDB_ID_NULL)
return false ;
}
else {
// dentro al grezzo
// -> movimento di risalita
SetFeed( GetEndFeed()) ;
Point3d ptAbove = ptLast + m_vtCorr * ( dElev + dSafeZ) ;
if ( AddLinearMove( ptAbove) == GDB_ID_NULL)
return false ;
// -> allineamento sopra al grezzo
Vector3d vtDir = OrthoCompo( ( ptDest - ptAbove), m_vtCorr) ;
if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL)
return false ;
// -> discesa al nuovo punto iniziale
SetFeed( GetTipFeed()) ;
if ( AddLinearMove( ptDest) == GDB_ID_NULL)
return false ;
}
}
// se il corrente è più fuori
else {
// allungo passata precedente
if ( AddLinearMove( ptLast + dDiff * vtNewDir) == GDB_ID_NULL)
return false ;
// inizio nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart + vtCorr * dDelta) == GDB_ID_NULL)
Point3d ptExtend = ptLast + dDiff * vtNewDir ;
if ( AddLinearMove( ptExtend) == GDB_ID_NULL)
return false ;
// inizio nuova passata, controllo se mi trovo fuori dal grezzo
Point3d ptDest = ptNewStart + vtCorr * dDelta ;
double dElev = 0. ;
if ( GetElevation( m_nPhase, ptExtend, ptDest, m_vtCorr, dElev) && dElev < EPS_SMALL) {
// fuori dal grezzo
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptDest) == GDB_ID_NULL)
return false ;
}
else {
// dentro la grezzo
// -> movimento di risalita
SetFeed( GetEndFeed()) ;
Point3d ptAbove = ptExtend + m_vtCorr * ( dElev + dSafeZ) ;
if ( AddLinearMove( ptAbove) == GDB_ID_NULL)
return false ;
// -> allineamento fuori dal grezzo
Vector3d vtDir = OrthoCompo( ( ptDest - ptAbove), m_vtCorr) ;
if ( AddLinearMove( ptAbove + vtDir) == GDB_ID_NULL)
return false ;
// -> discesa al nuovo punto finale
SetFeed( GetTipFeed()) ;
if ( AddLinearMove( ptDest) == GDB_ID_NULL)
return false ;
}
}
}
}
@@ -2088,7 +2180,7 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c
swap( ptOriStart, ptOriEnd) ;
vtNewDir.Invert() ;
}
}
}
// 4 -> retrazione
if ( bLast || m_Params.m_nLeadLinkType != SAWROU_LL_OUT) {
if ( ! AddRetract( ptNewEnd, vtCorr, dSafeZ, dElev, dAppr))
@@ -2099,339 +2191,6 @@ SawRoughing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, c
return true ;
}
//----------------------------------------------------------------------------
bool
SawRoughing::CalculateZConstCut( const ICurve* pCrv, double dXmin, double dXmax, bool bIncludeMax, bool bIncludeMin,
const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, const Frame3d& frSect,
const ISurfTriMesh* pStmRaw, const BBox3d& b3Raw, bool bExtend, double dDepth,
bool bFirstInterval, bool bLastInterval, int& nCount)
{
// calcolo step orizzontali
double dLargh = dXmax - dXmin ;
double dSideStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ;
int nSideStep = max( 1, static_cast<int>( ceil( dLargh / dSideStep))) ;
dSideStep = dLargh / nSideStep ;
// determino le coordinate x e y di tutte le intersezioni con la sezione ordinate per x decrescente
BBox3d b3Crv ;
pCrv->GetLocalBBox( b3Crv) ;
double dSectYMin = b3Crv.GetMin().y ;
double dSectYMax = b3Crv.GetMax().y ;
int nSize = nSideStep + ( bIncludeMax ? 1 : 0) + ( bIncludeMin ? 0 : -1) ;
DBLVECTOR vIntersX( nSize) ;
DBLVECTOR vIntersY( nSize) ;
int nStart = ( bIncludeMax ? 0 : 1) ;
int nEnd = ( bIncludeMin ? nSideStep : nSideStep - 1) ;
for ( int i = nStart ; i <= nEnd ; ++ i) {
vIntersX[i-nStart] = dXmax - i * dSideStep ;
if ( ! GetHeightOnSection( pCrv, vIntersX[i-nStart], dSectYMin, dSectYMax, vIntersY[i-nStart]))
return false ;
}
// calcolo elevazione
double dTotElev = - INFINITO ;
double dRefQuote = 0 ;
for ( int i = 0 ; i < int( vIntersX.size()) ; i++) {
Vector3d vtMove = vIntersX[i] * frSect.VersX() + vIntersY[i] * frSect.VersY() - 0.5 * m_TParams.m_dThick * m_vtTool ;
Vector3d vtThick = m_vtTool * m_TParams.m_dThick ;
Point3d ptStart = ptGdStart + vtMove ;
Point3d ptEnd = ptGdEnd + vtMove ;
Point3d ptStart2 = ptStart + vtThick ;
Point3d ptEnd2 = ptEnd + vtThick ;
AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw) ;
AdaptGuideLineToRaw( ptStart2, ptEnd2, vtGdDir, bExtend, pStmRaw) ;
// determino l'elevazione del taglio
double dCurrElev1, dCurrElev2 ;
if ( ! GetElevation( m_nPhase, ptStart, ptEnd, m_vtCorr, dCurrElev1) ||
! GetElevation( m_nPhase, ptStart2, ptEnd2, m_vtCorr, dCurrElev2)) {
m_pMchMgr->SetLastError( 2609, "Error in SawRoughing : GetElevation") ;
return false ;
}
double dCurrElev = max( dCurrElev1, dCurrElev2) ;
if ( dCurrElev > dTotElev) {
dTotElev = dCurrElev ;
dRefQuote = vIntersY[i] ;
}
else if ( abs( dCurrElev - dTotElev) < EPS_SMALL && dRefQuote > vIntersY[i])
dRefQuote = vIntersY[i] ;
}
// eventuale correzione con depth
double dRealElev = min( dTotElev, dDepth) ;
// calcolo step verticali
int nStep = ( m_Params.m_dStep < EPS_SMALL ? 1 : static_cast<int>( ceil( dRealElev / m_Params.m_dStep))) ;
nStep = max( 1, nStep) ;
double dStep = dRealElev / nStep ;
// costruisco un vettore con le quote di lavoro e gli indici delle ascisse in vIntersX da lavorare a quella quota
vector<pair<double, INTVECTOR>> vStepCoord ;
vStepCoord.reserve( nStep) ;
for ( int j = 1 ; j <= nStep ; j++) {
vStepCoord.emplace_back( dRefQuote + dTotElev - j * dStep, INTVECTOR()) ;
vStepCoord.back().second.reserve( vIntersX.size()) ;
for ( int i = 0 ; i < int( vIntersX.size()) ; i ++) {
// l'ascissa va considerata solo se la quota di lavoro è maggiore di quella della sezione
if ( vStepCoord.back().first > vIntersY[i] - EPS_SMALL)
vStepCoord.back().second.emplace_back(i) ;
}
// se non ci sono punti da lavorare alla quota corrente la scarto
if ( vStepCoord.back().second.empty())
vStepCoord.pop_back() ;
}
// individuo piani orizzontali extra da lavorare
int nStartSearch = vStepCoord.size() ;
const ICurveComposite* pCompo = GetCurveComposite( pCrv) ;
if ( pCompo != nullptr) {
for ( int i = 0 ; i < pCompo->GetCurveCount() ; i++) {
const ICurve* pSimpCrv = pCompo->GetCurve( i) ;
Point3d ptStart, ptEnd ;
pSimpCrv->GetStartPoint( ptStart) ;
pSimpCrv->GetEndPoint( ptEnd) ;
// verifico se è nell'intervallo da lavorare
if ( ptEnd.x > dXmax - EPS_SMALL)
continue ;
if ( ptStart.x < dXmin + EPS_SMALL)
break ;
// verifico se tratto orizzontale
if ( abs( ptEnd.y - ptStart.y) < EPS_SMALL) {
double dY = ( ptEnd.y + ptStart.y) / 2 ;
// se sotto la quota minima di lavoro lo ignoro
if ( dY < dRefQuote + dTotElev - dRealElev - EPS_SMALL)
continue ;
// se quota già considerata negli step ( ovvero è multiplo di dStep) la ignoro
if ( dStep < EPS_SMALL) {
if ( abs( dRefQuote + dTotElev - dY) < EPS_SMALL)
continue ;
}
else {
double dRes = ( dRefQuote + dTotElev - dY) / dStep ;
if ( dRes > EPS_SMALL && abs( dRes - round( dRes)) < EPS_SMALL)
continue ;
}
// verifico se piano orizzontale già individuato tra i piani extra
auto it = find_if( vStepCoord.begin() + nStartSearch, vStepCoord.end(), [dY]( const pair<double, INTVECTOR>& a)
{ return abs( a.first - dY) < EPS_SMALL ;}) ;
// se non individuato lo aggiungo
if ( it == vStepCoord.end()) {
vStepCoord.emplace_back( dY, INTVECTOR()) ;
vStepCoord.back().second.reserve( vIntersX.size()) ;
it = vStepCoord.end() - 1 ;
}
// calcolo le ascisse da lavorare corrispondenti al piano
for ( int j = 0 ; j < int( vIntersX.size()) ; j ++) {
if ( vIntersX[j] < ptEnd.x - EPS_SMALL)
break ;
if ( vIntersX[j] < ptStart.x + EPS_SMALL && vIntersX[j] > ptEnd.x - EPS_SMALL)
it->second.emplace_back( j) ;
}
// se non ci sono punti da lavorare lo ignoro
if ( it->second.empty())
vStepCoord.pop_back() ;
}
}
}
// riordino per quota di lavoro decrescente
sort( vStepCoord.begin(), vStepCoord.end(), []( const pair<double, INTVECTOR>& a, const pair<double, INTVECTOR>& b)
{ return a.first > b.first ;}) ;
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
double dLastX = 0 ;
double dElev = 0 ;
Point3d ptNewEnd ;
// ciclo sugli step verticali
for ( int j = 0 ; j < int( vStepCoord.size()) ; j++) {
// inverto lo step corrente se lo step precedente finisce più vicino all'ultima ascissa corrente
bool bInvertStep = false ;
if ( j > 0) {
double dXStepMax = vIntersX[vStepCoord[j].second.front()] ;
double dXStepMin = vIntersX[vStepCoord[j].second.back()] ;
if ( abs( dXStepMin - dLastX) < abs( dXStepMax - dLastX))
bInvertStep = true ;
}
// ciclo sui punti orizzontali
for ( int i = 0 ; i < int( vStepCoord[j].second.size()) ; ++ i) {
// se lo step è invertito leggo dal fondo
int nI = ( bInvertStep ? vStepCoord[j].second.size() - i - 1 : i) ;
// indice da considerare nel vettore delle coordinate
int nIdx = vStepCoord[j].second[nI] ;
bool bFirst = ( bFirstInterval && j == 0 && i == 0) ;
bool bLast = ( bLastInterval && j == vStepCoord.size() - 1 && i == vStepCoord[j].second.size() - 1) ;
bool bAlignedPoints = abs( dLastX - vIntersX[nIdx]) < EPS_SMALL ;
// 0 -> retrazione del precedente
if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) {
// se punto intermedio dello step corrente va sempre aggiunta
if ( i > 0) {
if ( ! AddRetract( ptNewEnd, m_vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
// se il punto è il primo dello step corrente va aggiunta solo se non è allineato con l'ultimo punto
// dello step precedente ( se allineati è semplice discesa senza rialzarsi)
else if ( j > 0 && ! bAlignedPoints) {
if ( ! AddRetract( ptNewEnd, m_vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
}
// calcolo punti di riferimento della guida alla quota della sezione
dLastX = vIntersX[nIdx] ;
double dY = vIntersY[nIdx] ;
Vector3d vtMove = dLastX * frSect.VersX() + dY * m_vtCorr - 0.5 * m_TParams.m_dThick * m_vtTool ;
Point3d ptStart = ptGdStart + vtMove ;
Point3d ptEnd = ptGdEnd + vtMove ;
// adatto la guida corrente al grezzo
AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw) ;
// quantità necessaria per arrivare alla quota di lavoro dalla quota della sezione
double dDelta = vStepCoord[j].first - dY ;
// vera elevazione alla quota della sezione
dElev = max( 0.0, dRefQuote + dTotElev - dY) ;
Point3d ptOriStart = ptStart ;
Point3d ptOriEnd = ptEnd ;
Point3d ptNewStart = ptOriStart ;
ptNewEnd = ptOriEnd ;
Vector3d vtNewDir = vtGdDir ;
// se attacco/uscita/collegamento esterno allungo inizio e fine
if ( m_Params.m_nLeadLinkType == SAWROU_LL_OUT) {
// distanza XY tra centro e bordo taglio
double dCurrElev = dElev - dDelta ;
double dDeltaT = 0 ;
if ( dCurrElev > 0.0 && dCurrElev < 0.5 * m_TParams.m_dDiam)
dDeltaT = sqrt( dCurrElev * m_TParams.m_dDiam - dCurrElev * dCurrElev) ;
double dDeltaTSt = dDeltaT ;
double dDeltaTEn = dDeltaT ;
// calcolo correzione per guida inclinata per far fuoriuscire la lama di tutto lo spessore
// ricavo il lato di uscita dal grezzo dello start
Vector3d vtRef = Y_AX ;
if ( abs( ptStart.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptStart.y - b3Raw.GetMax().y) < EPS_SMALL)
vtRef = X_AX ;
dDeltaTSt += m_TParams.m_dThick * ( vtGdDir * vtRef) / ( vtGdDir ^ vtRef).Len() ;
// end
vtRef = Y_AX ;
if ( abs( ptEnd.y - b3Raw.GetMin().y) < EPS_SMALL || abs( ptEnd.y - b3Raw.GetMax().y) < EPS_SMALL)
vtRef = X_AX ;
dDeltaTEn += m_TParams.m_dThick * ( vtGdDir * vtRef) / ( vtGdDir ^ vtRef).Len() ;
// modifico inizio
ptNewStart = ptOriStart - vtNewDir * ( dDeltaTSt + dAppr) ;
// modifico fine
ptNewEnd = ptOriEnd + vtNewDir * ( dDeltaTEn + dAppr) ;
}
// le passate dispari sono al contrario
if ( ( nCount % 2) != 0) {
swap( ptOriStart, ptOriEnd) ;
swap( ptNewStart, ptNewEnd) ;
vtNewDir.Invert() ;
}
// 1 -> approccio
if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) {
// se collegamento interno va fatto se è un intermedio, se è il primo del primo step oppure
// se è il primo di uno step intermedio ma non è allineato allo step precedente
if ( i > 0 || ( i == 0 && j == 0) || ( i == 0 && j > 0 && ! bAlignedPoints))
if ( ! AddApproach( ptNewStart, m_vtCorr, bFirst, dSafeZ, dElev, dAppr))
return false ;
}
// se collegamento out va fatto solo se è il primo in assoluto
else if ( bFirst)
if ( ! AddApproach( ptNewStart, m_vtCorr, bFirst, dSafeZ, dElev, dAppr))
return false ;
// 2 -> movimento in affondo al punto iniziale
// con attacco centrato sono sul materiale e devo usare feed di testa
if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) {
SetFlag( 0) ;
SetFeed( GetTipFeed()) ;
Point3d ptP2 = ptNewStart + m_vtCorr * dDelta ;
if ( AddLinearMove( ptP2) == GDB_ID_NULL)
return false ;
}
// con attacco fuori sono in aria
else {
if ( bFirst) {
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart + m_vtCorr * dDelta) == GDB_ID_NULL)
return false ;
}
else {
Point3d ptLast ;
GetCurrPos( ptLast) ;
double dDiff = ( ptNewStart - ptLast) * vtNewDir ;
// se precedente e corrente sono fuori allo stesso modo
if ( abs( dDiff) < 10 * EPS_SMALL) {
// inizio nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart + m_vtCorr * dDelta) == GDB_ID_NULL)
return false ;
}
// se il precedente è più fuori
else if ( dDiff > 0) {
// allungo nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart + m_vtCorr * dDelta - dDiff * vtNewDir) == GDB_ID_NULL)
return false ;
}
// se il corrente è più fuori
else {
// allungo passata precedente
if ( AddLinearMove( ptLast + dDiff * vtNewDir) == GDB_ID_NULL)
return false ;
// inizio nuova passata
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptNewStart + m_vtCorr * dDelta) == GDB_ID_NULL)
return false ;
}
}
}
// 3 -> movimento di lato al punto finale
if ( m_Params.m_nLeadLinkType != SAWROU_LL_OUT) {
SetFeed( GetFeed()) ;
Point3d ptP3 = ptNewEnd + m_vtCorr * dDelta ;
if ( AddLinearMove( ptP3) == GDB_ID_NULL)
return false ;
}
else {
SetFeed( GetFeed()) ;
if ( AddLinearMove( ptOriEnd + m_vtCorr * dDelta) == GDB_ID_NULL)
return false ;
SetFeed( GetEndFeed()) ;
if ( AddLinearMove( ptNewEnd + m_vtCorr * dDelta) == GDB_ID_NULL)
return false ;
}
// 4 -> retrazione soltanto se ultimo in assoluto oppure se attacco interno e ultimo dell'ultimo step
if ( bLast ||
( m_Params.m_nLeadLinkType != SAWROU_LL_OUT && j == vStepCoord.size() - 1 && i == vStepCoord[j].second.size() - 1)) {
if ( ! AddRetract( ptNewEnd, m_vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
// incremento contatore passate
++ nCount ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
SawRoughing::CalculateCurvedZigZagCut( const ICurve* pCut, const Vector3d& vtTool, double dElev, bool bFirst, bool bLast,
+3 -7
View File
@@ -89,16 +89,12 @@ class SawRoughing : public Machining
bool CalculateGuideLine( int nGuideId, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir) const ;
bool AdaptGuideLineToRaw( Point3d& ptGdStart, Point3d& ptGdEnd, const Vector3d& vtGdDir, bool bExtend, const ISurfTriMesh* pStmRaw) const ;
bool CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir,
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, const BBox3d& b3Raw) ;
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, const ISurfTriMesh* pStmRaw) ;
bool CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir,
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast,
int& nCount, const BBox3d& b3Raw) ;
bool CalculateZConstCut( const ICurve* pCrv, double dXmin, double dXmax, bool bIncludeMax, bool bIncludeMin,
const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, const Frame3d& frSect,
const ISurfTriMesh* pStmRaw, const BBox3d& b3Raw, bool bExtend, double dDepth,
bool bFirstInterval, bool bLastInterval, int& nCount) ;
int& nCount, const ISurfTriMesh* pStmRaw) ;
bool CalculateCurvedZigZagCut( const ICurve* pCut, const Vector3d& vtTool, double dElev, bool bFirst, bool bLast,
int& nCount) ;
int& nCount) ;
bool AddApproach( const Point3d& ptP, const Vector3d& vtCorr, bool bFirst,
double dSafeZ, double dElev, double dAppr) ;
bool AddRetract( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) ;