EgtMachKernel :

- prime modifiche per miglior gestione delle lavorazioni in doppio.
This commit is contained in:
Dario Sassi
2025-11-15 11:08:33 +01:00
parent 8282548bf0
commit ae9bc56917
6 changed files with 286 additions and 107 deletions
+146 -94
View File
@@ -180,11 +180,11 @@ Operation::GetToolpathsStatus( int& nCnt, int& nEmpty) const
//----------------------------------------------------------------------------
int
Operation::GetFirstFullToolpath( void) const
Operation::GetFirstFullToolpath( bool bMain) const
{
if ( m_pGeomDB == nullptr)
return GDB_ID_NULL ;
int nClPath = m_pGeomDB->GetFirstGroupInGroup( m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL)) ;
int nClPath = m_pGeomDB->GetFirstGroupInGroup( m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, ( bMain ? MCH_CL : MCH_DBL))) ;
while ( nClPath != GDB_ID_NULL && m_pGeomDB->GetFirstInGroup( nClPath) == GDB_ID_NULL)
nClPath = m_pGeomDB->GetNextGroup( nClPath) ;
return nClPath ;
@@ -202,11 +202,11 @@ Operation::GetNextFullToolpath( int nClPathId) const
//----------------------------------------------------------------------------
int
Operation::GetLastFullToolpath( void) const
Operation::GetLastFullToolpath( bool bMain) const
{
if ( m_pGeomDB == nullptr)
return GDB_ID_NULL ;
int nClPath = m_pGeomDB->GetLastGroupInGroup( m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL)) ;
int nClPath = m_pGeomDB->GetLastGroupInGroup( m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, ( bMain ? MCH_CL : MCH_DBL))) ;
while ( nClPath != GDB_ID_NULL && m_pGeomDB->GetFirstInGroup( nClPath) == GDB_ID_NULL)
nClPath = m_pGeomDB->GetPrevGroup( nClPath) ;
return nClPath ;
@@ -1557,55 +1557,6 @@ Operation::CalcAndSetAxesBBox( void)
return true ;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
bool
Operation::CalcMirrorByDouble( int nClId, const string& sUserNotes)
{
// verifico se prevista lavorazione in doppio
int nDouble ;
if ( ! GetValInNotes( sUserNotes, UN_DOUBLE, nDouble) ||
( nDouble != 1 && nDouble != 2 && nDouble != 3))
return true ;
// copio gruppo di lavorazione e cambio nome
int nDblId = m_pGeomDB->Copy( nClId, GDB_ID_NULL, nClId, GDB_AFTER) ;
if ( nDblId == GDB_ID_NULL)
return false ;
m_pGeomDB->SetName( nDblId, MCH_DBL) ;
// assegno colore di copia
int nClPathId = m_pGeomDB->GetFirstGroupInGroup( nDblId) ;
while ( nClPathId != GDB_ID_NULL) {
m_pGeomDB->SetMaterial( nClPathId, GRAY) ;
nClPathId = m_pGeomDB->GetNextGroup( nClPathId) ;
}
// determino posizione del piano di mirroring
BBox3d b3Raw ;
Point3d ptOn ;
if ( ! GetCurrRawsGlobBox( b3Raw) || ! b3Raw.GetCenter( ptOn))
return false ;
Vector3d vtNorm ;
switch ( nDouble) {
case 1 : vtNorm = X_AX ; break ;
case 2 : vtNorm = Y_AX ; break ;
case 3 : vtNorm = Z_AX ; break ;
}
double dPlanePos ;
if ( GetValInNotes( sUserNotes, UN_MIRRORAX, dPlanePos))
ptOn = b3Raw.GetMin() + dPlanePos * vtNorm ;
// eseguo mirroring rispetto a piano opportuno
m_pGeomDB->MirrorGroup( nDblId, ptOn, vtNorm) ;
// se presente una differenza in Z, eseguo spostamento
double dDeltaZ ;
if ( GetValInNotes( sUserNotes, UN_DELTAZ, dDeltaZ) && abs( dDeltaZ) > EPS_SMALL)
m_pGeomDB->TranslateGlob( nDblId, Vector3d( 0, 0, dDeltaZ)) ;
return true ;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
bool
@@ -1809,6 +1760,55 @@ Operation::SetBlockedRotAxis( const string& sBlockedAxis) const
return m_pMchMgr->SetRotAxisBlock( sKey, dVal) ;
}
//----------------------------------------------------------------------------
bool
Operation::ApplyHintToPrevAxRot( const string& sHint, const Machine* pMch, DBLVECTOR& vAxRotPrec)
{
// verifico validità macchina
if ( pMch == nullptr)
return false ;
// recupero il numero di assi lineari e rotanti attivi
int nLinAxes = pMch->GetCurrLinAxes() ;
int nRotAxes = pMch->GetCurrRotAxes() ;
// verifico validità vettore assi rotanti precedenti
if ( ssize( vAxRotPrec) < nRotAxes)
return false ;
// eseguo
STRVECTOR vsTok ;
Tokenize( sHint, ",;", vsTok) ;
for ( const auto& sTok : vsTok) {
if ( sTok.empty())
continue ;
string szKey, szVal ;
Split( sTok, "=", true, szKey, szVal) ;
Trim( szKey) ;
for ( int i = 0 ; i < nRotAxes ; ++ i) {
string sAxToken ;
if ( pMch->GetCurrAxisToken( nLinAxes + i, sAxToken) &&
szKey == Trim( sAxToken, " \t\r\n=")) {
double dVal ;
if ( FromString( szVal, dVal)) {
double dOffset = 0 ;
pMch->GetCurrAxisOffset( nLinAxes + i, dOffset) ;
if ( abs( dOffset) > EPS_ANG_SMALL)
dVal -= dOffset ;
bool bInvert = false ;
pMch->GetCurrAxisInvert( nLinAxes + i, bInvert) ;
if ( bInvert)
dVal = -dVal ;
vAxRotPrec[i] = dVal ;
}
break ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Operation::CalculateAxesValues( const string& sHint, bool bSolChExact, double dSingConeAng)
@@ -1871,36 +1871,8 @@ Operation::CalculateAxesValues( const string& sHint, bool bSolChExact, double dS
vAxRotPrec = vAxRotHome ;
}
// se ci sono suggerimenti validi per gli assi rotanti, li applico
if ( ! bHintHome && ! sHint.empty()) {
STRVECTOR vsTok ;
Tokenize( sHint, ",;", vsTok) ;
for ( const auto& sTok : vsTok) {
if ( sTok.empty())
continue ;
string szKey, szVal ;
Split( sTok, "=", true, szKey, szVal) ;
Trim( szKey) ;
for ( int i = 0 ; i < nRotAxes ; ++ i) {
string sAxToken ;
if ( pMch->GetCurrAxisToken( nLinAxes + i, sAxToken) &&
szKey == Trim( sAxToken, " \t\r\n=")) {
double dVal ;
if ( FromString( szVal, dVal)) {
double dOffset = 0 ;
pMch->GetCurrAxisOffset( nLinAxes + i, dOffset) ;
if ( abs( dOffset) > EPS_ANG_SMALL)
dVal -= dOffset ;
bool bInvert = false ;
pMch->GetCurrAxisInvert( nLinAxes + i, bInvert) ;
if ( bInvert)
dVal = -dVal ;
vAxRotPrec[i] = dVal ;
}
break ;
}
}
}
}
if ( ! bHintHome && ! sHint.empty())
ApplyHintToPrevAxRot( sHint, pMch, vAxRotPrec) ;
// recupero la minima differenza angolare da posizione precedente per stare vicino a posizione home
double dAngDeltaMinForHome = pMch->GetAngDeltaMinForHome() ;
@@ -1943,6 +1915,81 @@ Operation::CalculateAxesValues( const string& sHint, bool bSolChExact, double dS
return bOk ;
}
//----------------------------------------------------------------------------
bool
Operation::CalculateDoubleAxesValues( const string& sHint, bool bSolChExact, double dSingConeAng)
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// recupero macchina corrente
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr)
return false ;
// non si considera la lavorazione precedente (almeno per ora)
// l'utensile per i calcoli macchina deve essere già stato impostato
// recupero il numero di assi lineari e rotanti attivi
int nLinAxes = pMch->GetCurrLinAxes() ;
int nRotAxes = pMch->GetCurrRotAxes() ;
// recupero gli angoli home
DBLVECTOR vAxRotHome( nRotAxes, 0.) ;
DBLVECTOR vAxHome ;
pMch->GetAllCurrAxesHomePos( vAxHome) ;
for ( int i = 0 ; i < nRotAxes ; ++ i)
vAxRotHome[i] = vAxHome[nLinAxes + i] ;
// Verifico se nei suggerimenti viene richiesta Home per gli assi
bool bHintHome = ( sHint.find( "Home") != string::npos) ;
// Assegno gli angoli iniziali
DBLVECTOR vAxRotPrec( nRotAxes, 0.) ;
DBLVECTOR vAxVal ;
// uso gli angoli home
vAxRotPrec = vAxRotHome ;
// se ci sono suggerimenti validi per gli assi rotanti, li applico
if ( ! bHintHome && ! sHint.empty())
ApplyHintToPrevAxRot( sHint, pMch, vAxRotPrec) ;
// recupero la minima differenza angolare da posizione precedente per stare vicino a posizione home
double dAngDeltaMinForHome = pMch->GetAngDeltaMinForHome() ;
// applico eventuali blocchi di assi rotanti
m_pMchMgr->ApplyRotAxisBlock() ;
// applico il criterio di scelta della soluzione quando molteplici
pMch->SetSolCh( GetSolCh(), bSolChExact) ;
// applico angolo di apertura cono da direzione singolare
pMch->SetSingConeAng( dSingConeAng) ;
// recupero gruppo della geometria di lavorazione in doppio ( Double Cutter Location)
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_DBL) ;
if ( nClId == GDB_ID_NULL)
return false ;
// calcolo il valore degli assi macchina di tutti i movimenti
bool bOk = true ;
if ( pMch->GetCurrKinematicChainType() == KIN_CHAIN_MCENT) {
int nClPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ;
while ( nClPathId != GDB_ID_NULL) {
if ( ! CalculateClPathMcentAxesValues( nClPathId, dAngDeltaMinForHome, vAxRotHome, vAxRotPrec))
bOk = false ;
nClPathId = m_pGeomDB->GetNextGroup( nClPathId) ;
}
}
else if ( pMch->GetCurrKinematicChainType() == KIN_CHAIN_ROBOT) {
LOG_ERROR( GetEMkLogger(), "Error : double machining with robot not managed") ;
bOk = false ;
}
else
bOk = false ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
Operation::CalculateClPathMcentAxesValues( int nClPathId, double dAngDeltaMinForHome, const DBLVECTOR& vAxRotHome,
@@ -3558,6 +3605,7 @@ Operation::AdjustOneStartEndMovement( int nClPathId, int nPrevClPathId, Operatio
}
// modifico quella originale (è la prima del percorso)
m_pGeomDB->SetName( nEntId, MCH_CL_CLIMB) ;
m_pGeomDB->RemoveInfo( nEntId, KEY_CL_DOUBLE) ;
DBLVECTOR vAxNew = vAxCurr ;
vAxNew[2] = dHomeZ ;
int nFlagNew = 2 ;
@@ -3668,6 +3716,7 @@ Operation::AdjustOneStartEndMovement( int nClPathId, int nPrevClPathId, Operatio
return false ;
// modifico l'entità originale (è la prima del percorso)
m_pGeomDB->SetName( nEntId, MCH_CL_CLIMB) ;
m_pGeomDB->RemoveInfo( nEntId, KEY_CL_DOUBLE) ;
DBLVECTOR vAxNew = vAxCurr ;
vAxNew[2] = vAxNew1[2] ;
int nFlagNew = 2 ;
@@ -3736,6 +3785,7 @@ Operation::AdjustOneStartEndMovement( int nClPathId, int nPrevClPathId, Operatio
return false ;
// modifico l'entità originale (è la prima del percorso)
m_pGeomDB->SetName( nEntId, MCH_CL_CLIMB) ;
m_pGeomDB->RemoveInfo( nEntId, KEY_CL_DOUBLE) ;
DBLVECTOR vAxNew = vAxCurr ;
vAxNew[2] = vAxPrev[2] ;
int nFlagNew = 2 ;
@@ -3774,6 +3824,7 @@ Operation::AdjustOneStartEndMovement( int nClPathId, int nPrevClPathId, Operatio
return false ;
// modifico l'entità originale (è la prima del percorso)
m_pGeomDB->SetName( nEntId, MCH_CL_CLIMB) ;
m_pGeomDB->RemoveInfo( nEntId, KEY_CL_DOUBLE) ;
DBLVECTOR vAxNew = pCamData->GetAxesVal() ;
for ( int i = 0 ; i < 2 ; ++ i) {
bool bLinear, bHead ; pMch->GetCurrAxisType( i, bLinear, bHead) ;
@@ -4006,19 +4057,19 @@ Operation::AddSpecialClimb( const DBLVECTOR& vAxVal, bool bOk, int nClPathId,
//----------------------------------------------------------------------------
bool
Operation::RemoveClimb( int nClPathId)
Operation::RemoveClimb( int nClPathId, bool bMain)
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// se percorso CL specificato, verifico appartenga al gruppo della geometria di lavorazione (Cutter Location)
if ( nClPathId != GDB_ID_NULL) {
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_CL) ;
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), ( bMain ? MCH_CL : MCH_DBL)) ;
if ( nClId == GDB_ID_NULL || m_pGeomDB->GetParentId( nClPathId) != nClId)
return false ;
}
// altrimenti, recupero il primo percorso CL non vuoto della operazione
else {
nClPathId = GetFirstFullToolpath() ;
nClPathId = GetFirstFullToolpath( bMain) ;
if ( nClPathId == GDB_ID_NULL)
return false ;
}
@@ -4059,7 +4110,7 @@ Operation::AddRise( DBLVECTOR& vAxVal, double dDelta, int nClPathId, int nToMinM
if ( pCamData == nullptr)
return false ;
// se risalita praticamente nulla, esco con successo
if ( abs( dDelta) < 10 * EPS_SMALL) {
if ( isfinite( dDelta) && abs( dDelta) < 10 * EPS_SMALL) {
// recupero i valori degli assi
vAxVal = pCamData->GetAxesVal() ;
return ( vAxVal.size() >= 3) ;
@@ -4294,19 +4345,19 @@ Operation::AddSpecialRise( const DBLVECTOR& vAxVal, bool bOk, int nClPathId,
//----------------------------------------------------------------------------
bool
Operation::RemoveRise( int nClPathId)
Operation::RemoveRise( int nClPathId, bool bMain)
{
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// se percorso CL specificato, verifico appartenga al gruppo della geometria di lavorazione (Cutter Location)
if ( nClPathId != GDB_ID_NULL) {
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), MCH_CL) ;
int nClId = m_pGeomDB->GetFirstNameInGroup( GetOwner(), ( bMain ? MCH_CL : MCH_DBL)) ;
if ( nClId == GDB_ID_NULL || m_pGeomDB->GetParentId( nClPathId) != nClId)
return false ;
}
// altrimenti, recupero l'ultimo percorso CL non vuoto della operazione
else {
nClPathId = GetLastFullToolpath() ;
nClPathId = GetLastFullToolpath( bMain) ;
if ( nClPathId == GDB_ID_NULL)
return false ;
}
@@ -4397,14 +4448,14 @@ Operation::RemoveHome( void)
//----------------------------------------------------------------------------
bool
Operation::RemoveClimbRiseHome( void)
Operation::RemoveClimbRiseHome( bool bMain)
{
// elimino le entità CLIMB, RISE e HOME delle diverse path dell'operazione
int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ;
int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, ( bMain ? MCH_CL : MCH_DBL)) ;
int nClPathId = m_pGeomDB->GetFirstGroupInGroup( nClId) ;
while ( nClPathId != GDB_ID_NULL) {
RemoveClimb( nClPathId) ;
RemoveRise( nClPathId) ;
RemoveClimb( nClPathId, bMain) ;
RemoveRise( nClPathId, bMain) ;
nClPathId = m_pGeomDB->GetNextGroup( nClPathId) ;
}
return ( nClId != GDB_ID_NULL) ;
@@ -4434,6 +4485,7 @@ Operation::AddRobotClimb( int nEntId, double dDeltaZ)
return false ;
// modifico quella originale (è la prima del percorso)
m_pGeomDB->SetName( nEntId, MCH_CL_CLIMB) ;
m_pGeomDB->RemoveInfo( nEntId, KEY_CL_DOUBLE) ;
pCdEnt->SetAxes( CamData::AS_OK, vAxClimb) ;
pCdEnt->SetFlag( 2) ;
pCdEnt->SetFlag2( ( bZmax ? 1 : 0)) ;