Merge commit '5d77408018aa0c4088577770e8bca60d24cfe833'

This commit is contained in:
Dario Sassi
2025-01-30 19:35:11 +01:00
2 changed files with 477 additions and 97 deletions
+471 -94
View File
@@ -60,11 +60,22 @@ using namespace std ;
// 2156 = "Warning in Drilling : Skipped by Standard Drilling "
// 2157 = "Warning in Drilling : Skipped by Peck Drilling "
//----------------------------------------------------------------------------
// debug
#define ENABLE_DEBUG_MULTIHEAD_HOLES 0
//----------------------------------------------------------------------------
// definizione delle costanti
const int IND_TOOL_INVALID = -1 ;
const int IND_HOLE_INVALID = -1 ;
//----------------------------------------------------------------------------
// definizione tipologia foratura
const int DRILL_TYPE_ERR = 0 ;
const int DRILL_TYPE_STD = 1 ; // 1 tool
const int DRILL_TYPE_MULTI_FIXED = 2 ; // più utensili fissi
const int DRILL_TYPE_MULTI_SEL = 3 ; // più utensili selezionabili
//----------------------------------------------------------------------------
// struttura semplificata del foro
struct Hole {
@@ -112,10 +123,13 @@ struct ToolInfo {
// struttura per foratura con MultiHeadDrills
struct MHDrill {
int nInd_id_hole ; // indice foro
Vector3d vtAux ; // vettore ausiliario per tale foratura
int nInd_id_hole ; // indice foro
Vector3d vtAux ; // vettore ausiliario per tale foratura
INTVECTOR vActiveExist ; // nel caso di più utensili selezionabili, contiene gli indici delle uscite attive
MHDrill( int nIndH, Vector3d vtA)
: nInd_id_hole( nIndH), vtAux( vtA) {} ;
MHDrill( int nIndH, Vector3d vtA, INTVECTOR vAE)
: nInd_id_hole( nIndH), vtAux( vtA), vActiveExist( vAE) {} ;
} ;
@@ -746,21 +760,21 @@ Drilling::Update( bool bPostApply)
}
//----------------------------------------------------------------------------
bool
int
Drilling::VerifyMultiParallelFixedDrills( void)
{
// se aggregato da sotto, sicuramente con una sola punta
bool bAggrBottom = IsAggrBottom( m_TParams.m_sHead) ;
if ( bAggrBottom)
return false ;
return DRILL_TYPE_STD ;
// se una sola uscita, inutile continuare
int nExitCnt = m_pMchMgr->GetCurrMachine()->GetHeadExitCount( m_TParams.m_sHead) ;
if ( nExitCnt == 1)
return false ;
return DRILL_TYPE_STD ;
// verifico che le uscite siano fisse
int nSelectType = m_pMchMgr->GetCurrMachine()->GetHeadSelectType( m_TParams.m_sHead) ;
if ( nSelectType != MCH_SLT_FIXEDEXITS)
return false ;
if ( nSelectType != MCH_SLT_FIXEDEXITS && nSelectType != MCH_SLT_MULTIEXITS)
return DRILL_TYPE_STD ;
// recupero la direzione dell'utensile principale
Point3d ptMainExit ; Vector3d vtMainTool, vtMainAux ;
m_pMchMgr->GetCurrMachine()->GetHeadExitPosDirAux( m_TParams.m_sHead, m_TParams.m_nExit, ptMainExit, vtMainTool, vtMainAux) ;
@@ -781,28 +795,55 @@ Drilling::VerifyMultiParallelFixedDrills( void)
// verifico punta o fresa con direzione corretta
Point3d ptExit ; Vector3d vtTool, vtAux ;
if ( ( ( nType & TF_DRILLBIT) != 0 || nType == TT_MILL_STD) &&
m_pMchMgr->GetCurrMachine()->GetHeadExitPosDirAux(m_TParams.m_sHead, nT + 1, ptExit, vtTool, vtAux) &&
AreSameVectorApprox( vtTool, vtMainTool))
return true ;
m_pMchMgr->GetCurrMachine()->GetHeadExitPosDirAux( m_TParams.m_sHead, nT + 1, ptExit, vtTool, vtAux) &&
AreSameVectorApprox( vtTool, vtMainTool)) {
if ( nSelectType == MCH_SLT_FIXEDEXITS)
return DRILL_TYPE_MULTI_FIXED ;
else
return DRILL_TYPE_MULTI_SEL ;
}
}
}
// non è stato trovato niente
return false ;
return DRILL_TYPE_STD ;
}
//----------------------------------------------------------------------------
bool
Drilling::StandardProcess( bool bRecalc, int nPvId, int nClId)
{
// se ho almeno un'altra punta fissa parallela alla principale ...
if ( VerifyMultiParallelFixedDrills()) {
// recupero il tipo di lavorazione
int nDrillType = VerifyMultiParallelFixedDrills() ;
// eseguo la lavorazione richiesta
switch ( nDrillType) {
case DRILL_TYPE_STD : {
// elaboro i singoli fori
for ( int i = 0 ; i < int( m_vId.size()) ; ++ i) {
const auto& vId = m_vId[i] ;
// se richiesto preview
if ( nPvId != GDB_ID_NULL) {
if ( ! GenerateHolePv( i, vId, MCH_PATH, nPvId))
return false ;
// creo la regione di ingombro del foro
int nDriId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetLastGroupInGroup( nPvId)) ;
GenerateHoleRegionPv( nDriId, 1, nPvId) ;
}
// se richiesta lavorazione
if ( nClId != GDB_ID_NULL) {
if ( ! GenerateHoleCl( i, vId, MCH_PATH, nClId))
return false ;
}
}
}
break ;
case DRILL_TYPE_MULTI_FIXED : {
TABMHDRILL tabDrills ;
double dMHOff = 0 ;
if ( ! MultiHeadDrilling( m_vId, nClId, tabDrills, dMHOff))
if ( ! MultiHeadDrilling( m_vId, nClId, true, tabDrills, dMHOff))
return false ;
if ( tabDrills.empty())
return true ;
for ( int i = 0 ; i < int( tabDrills.size()) ; ++i) {
for ( int i = 0 ; i < int( tabDrills.size()) ; ++ i) {
// se richiesto preview
if ( nPvId != GDB_ID_NULL) {
if ( ! GenerateHolePv( i, m_vId[tabDrills[i].nInd_id_hole], MCH_PATH, nPvId))
@@ -817,25 +858,53 @@ Drilling::StandardProcess( bool bRecalc, int nPvId, int nClId)
return false ;
}
}
return true ;
}
// ... altrimenti elaboro i singoli fori
for ( int i = 0 ; i < int( m_vId.size()) ; ++ i) {
const auto& vId = m_vId[i] ;
// se richiesto preview
if ( nPvId != GDB_ID_NULL) {
if ( ! GenerateHolePv( i, vId, MCH_PATH, nPvId))
return false ;
// creo la regione di ingombro del foro
int nDriId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetLastGroupInGroup( nPvId)) ;
GenerateHoleRegionPv( nDriId, 1, nPvId) ;
}
// se richiesta lavorazione
if ( nClId != GDB_ID_NULL) {
if ( ! GenerateHoleCl( i, vId, MCH_PATH, nClId))
return false ;
break ;
case DRILL_TYPE_MULTI_SEL : {
// eseguo il MultiHead drilling per gruppo a forare
TABMHDRILL tabDrills ;
double dMHOff = 0 ;
if ( ! MultiHeadDrilling( m_vId, nClId, false, tabDrills, dMHOff))
return false ;
if ( tabDrills.empty())
return true ;
for ( int i = 0 ; i < int( tabDrills.size()) ; ++ i) {
// se richiesto preview
if ( nPvId != GDB_ID_NULL) {
if ( ! GenerateHolePv( i, m_vId[tabDrills[i].nInd_id_hole], MCH_PATH, nPvId))
return false ;
// creo la regione di ingombro del foro
int nDriId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetLastGroupInGroup( nPvId)) ;
GenerateHoleRegionPv( nDriId, 1, nPvId) ;
}
// se richiesta lavorazione
if ( nClId != GDB_ID_NULL) {
if ( ! GenerateHoleCl( i, m_vId[tabDrills[i].nInd_id_hole], MCH_PATH, nClId, dMHOff, tabDrills[i].vtAux))
return false ;
}
#if ENABLE_DEBUG_MULTIHEAD_HOLES
LOG_ERROR( GetEMkLogger(), ( " --- Tool main in " + ToString( m_vId[tabDrills[i].nInd_id_hole].nId)).c_str()) ;
string sActiveTool = "" ;
for ( int _a = 0 ; _a < int( tabDrills[i].vActiveExist.size()) ; ++ _a)
sActiveTool.append( "->" + ToString( tabDrills[i].vActiveExist[_a])) ;
LOG_ERROR( GetEMkLogger(), ( " Uscite attive : " + sActiveTool).c_str()) ;
string s_vtAux = "{" ;
s_vtAux.append( ToString( tabDrills[i].vtAux.x) + ", ") ;
s_vtAux.append( ToString( tabDrills[i].vtAux.y) + ", ") ;
s_vtAux.append( ToString( tabDrills[i].vtAux.z) + "}") ;
LOG_ERROR( GetEMkLogger(), ( " vtAux : " + s_vtAux).c_str()) ;
#endif
// ----------------------------------------------------------
}
}
break ;
case DRILL_TYPE_ERR :
return false ;
default :
break ;
}
return true ;
}
@@ -935,6 +1004,218 @@ Drilling::GetClosestHolesToHole( const VECTORHOLE& vHoles, int nMyInd, bool bDri
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::OrderConfigsForSelectableTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndToolMain, TABMHDRILL& vDrills)
{
// se non ho fori, allora non faccio nulla
vDrills.clear() ;
if ( vHoles.empty())
return true ;
// recupero gli indici dei fori non lavorabili
INTVECTOR vIndUndrilledHoles ;
for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) {
// scorro sulle configurazioni trovate
bool bIsUndrilled = true ;
for ( int j = 0 ; j < int( vHoles[i].vIndTools.size()) && bIsUndrilled ; ++ j)
bIsUndrilled = ( vHoles[i].vIndTools[j] == IND_TOOL_INVALID &&
vHoles[i].vToolHole[j] == IND_TOOL_INVALID &&
! vHoles[i].vVtAux[j].IsValid()) ;
// se foro non lavorabile, lo inserisco nel vettore
if ( bIsUndrilled)
vIndUndrilledHoles.emplace_back( i) ;
}
// recupero il numero di fori totali
int nHoles = int( vHoles.size()) ;
// recupero il numero di fori non lavorabili
int nUndrilledHoles = int( vIndUndrilledHoles.size()) ;
// se i due valori coincidono, allora ho finito
if ( nHoles == nUndrilledHoles)
return true ;
// considero tutti i fori come non lavorati
for ( int i = 0 ; i < nHoles ; ++ i)
vHoles[i].bTempDrill = false ;
// inizializzo contatore di fori lavorati
int nDrilledHoles = 0 ;
// finchè non lavoro tutti i fori ammissibili
const int MAXTRY = 5000 ;
int nCont = 0 ;
while ( nDrilledHoles < nHoles - nUndrilledHoles && nCont < MAXTRY) {
// cerco la(e) configurazione(i) che lavora(no) più fori
INTVECTOR vIndBestConfigs ;
GetConfigsWithMoreDrilledHoles( vHoles, vIndBestConfigs) ;
// se non ho trovato nessuna configurazione, allora non faccio nulla
if ( vIndBestConfigs.empty())
break ;
int nBestConfig = vIndBestConfigs[0] ;
ChooseBestConfigForSelectableTools( vHoles, nIndToolMain, vIndBestConfigs, nBestConfig) ;
// imposto bTempDrill per i fori in esame
INTVECTOR vIndActiveExits ;
int nRefHole = 0 ;
for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) {
if ( ! vHoles[i].bTempDrill &&
vHoles[i].vIndTools[nBestConfig] != IND_TOOL_INVALID &&
vHoles[i].vToolHole[nBestConfig] != IND_TOOL_INVALID &&
vHoles[i].vVtAux[nBestConfig].IsValid()) {
// flag per lavorazione temporanea
vHoles[i].bTempDrill = true ;
// aumento contatore fori lavorati
++ nDrilledHoles ;
// ricavo la testa su cui è montato l'utensile
vIndActiveExits.emplace_back( vTools[vHoles[i].vIndTools[nBestConfig]].pTool->m_nExit) ;
// memorizzo un foro di riferimento
nRefHole = i ;
}
}
// inserisco la configurazione per la lavorazione
vDrills.emplace_back( vHoles[nRefHole].vToolHole[nBestConfig],
vHoles[nRefHole].vVtAux[nBestConfig],
vIndActiveExits) ;
// incremento contatore tentativi massimi
++ nCont ;
}
// se ho superato i tentativi massimi, errore
if ( nCont == MAXTRY) {
vDrills.clear() ;
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::ChooseBestConfigForSelectableTools( const VECTORHOLE& vHoles, int nIndToolMain,
INTVECTOR& vConfInds, int& nBestConf)
{
/*
algoritmo Greedy per la scelta della miglior configurazione per tool selezionabili
*/
// se non ho fori, allora ho finito
if ( vHoles.empty())
return true ;
// se non ho configurazioni, allora ho finito
if ( vConfInds.empty())
return true ;
// per sicurezza la prima configurazione è la migliore ( decisione temporanea )
nBestConf = vConfInds[0] ;
// se ho una sola configurazione, allora è quella ottimale
if ( int( vConfInds.size()) == 1)
return true ;
// euristicamente considero accettabili solo le configurazioni dove compare il tool principale
// ( se non la trovo scelgo semplicemente la prima )
INTVECTOR vConfInds_Greedy0 ;
for ( int nC = 0 ; nC < int( vConfInds.size()) ; ++ nC) {
int nMyConfig = vConfInds[nC] ;
for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) {
if ( ! vHoles[i].bTempDrill &&
vHoles[i].vIndTools[nMyConfig] == nIndToolMain &&
vHoles[i].vToolHole[nMyConfig] != IND_TOOL_INVALID &&
vHoles[i].vVtAux[nMyConfig].IsValid()) {
vConfInds_Greedy0.emplace_back( vConfInds[nC]) ;
break ;
}
}
}
// se ho meno di due configurazioni, ho trovato quella "ottimale"
if ( int( vConfInds_Greedy0.size()) < 2) {
if ( ! vConfInds_Greedy0.empty())
nBestConf = vConfInds_Greedy0[0] ;
return true ;
}
// cerco tra le configurazioni trovate, quella che inserisce il tool main in un foro non lavorato
INTVECTOR vConfInds_Greedy1 ;
for ( int nC = 0 ; nC < int( vConfInds_Greedy0.size()) ; ++ nC) {
int nMyConfig = vConfInds_Greedy0[nC] ;
for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) {
if ( ! vHoles[i].bTempDrill &&
vHoles[i].vIndTools[nMyConfig] == nIndToolMain &&
vHoles[i].vToolHole[nMyConfig] == i &&
vHoles[i].vVtAux[nMyConfig].IsValid()) {
vConfInds_Greedy1.emplace_back( vConfInds_Greedy0[nC]) ;
break ;
}
}
}
// se ho meno di due configurazioni, ho trovato quella "ottimale"
if ( int( vConfInds_Greedy1.size()) < 2) {
if ( ! vConfInds_Greedy1.empty())
nBestConf = vConfInds_Greedy1[0] ;
return true ;
}
// ... servono altri test di ottimizzazione ? ...
nBestConf = vConfInds_Greedy1[0] ;
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::GetConfigsWithMoreDrilledHoles( const VECTORHOLE& vHoles, INTVECTOR& vInds)
{
/*
controllando il parambetro bTempDrilled, la funzione restituisce la configurazione
( le configurazioni ) che svuotano il maggior numero di fori
*/
// se non ho fori, allora non faccio nulla
vInds.clear() ;
if ( vHoles.empty())
return true ;
// scrorro le configurazioni presenti
int nMaxDrilled = 0 ;
for ( int nC = 0 ; nC < int( vHoles[0].vToolHole.size()) ; ++ nC) {
// scorro i fori
int nCurrDrilled = 0 ;
for ( int nH = 0 ; nH < int( vHoles.size()) ; ++ nH) {
// se il foro è già lavorato, passo al successivo
if ( vHoles[nH].bTempDrill)
continue ;
// controllo se il foro non lavorato ha una configurazione valida
if ( vHoles[nH].vToolHole[nC] != IND_TOOL_INVALID &&
vHoles[nH].vIndTools[nC] != IND_TOOL_INVALID &&
vHoles[nH].vVtAux[nC].IsValid())
++ nCurrDrilled ;
}
if ( nCurrDrilled > nMaxDrilled)
nMaxDrilled = nCurrDrilled ;
}
// se non ho trovato configurazioni, vuol dire che tutti i fori sono lavorati o che non
// esiste una configurazione ammissibile
if ( nMaxDrilled == 0)
return true ;
// cerco tutte le configurazioni che svuotano nMaxDrilled fori
for ( int nC = 0 ; nC < int( vHoles[0].vToolHole.size()) ; ++ nC) {
// scorro i fori
int nCurrDrilled = 0 ;
for ( int nH = 0 ; nH < int( vHoles.size()) ; ++ nH) {
// se il foro è già lavorato, passo al successivo
if ( vHoles[nH].bTempDrill)
continue ;
// controllo se il foro non lavorato ha una configurazione valida
if ( vHoles[nH].vToolHole[nC] != IND_TOOL_INVALID &&
vHoles[nH].vIndTools[nC] != IND_TOOL_INVALID &&
vHoles[nH].vVtAux[nC].IsValid())
++ nCurrDrilled ;
}
if ( nCurrDrilled == nMaxDrilled)
vInds.emplace_back( nC) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::EraseDuplicatedConfigs( VECTORHOLE& vHoles)
@@ -1224,10 +1505,9 @@ Drilling::GetHoleBestConfig( VECTORHOLE& vHoles, int nInd, TABMHDRILL& tabDrills
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDrills, double& dMHOff)
Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, bool bFixed, TABMHDRILL& tabDrills, double& dMHOff)
{
// controllo parametri
tabDrills.clear() ;
@@ -1251,7 +1531,7 @@ Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDri
for ( int nT = 0 ; nT < nExitCnt ; ++ nT) {
string sToolName ;
if ( ! m_pMchMgr->GetLoadedTool( sHead, nT + 1, sToolName) || sToolName.empty()) {
// non c'è utensile
// non c'è utensile
vTools.emplace_back( nullptr) ;
continue ;
}
@@ -1339,9 +1619,52 @@ Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDri
m_pMchMgr->ApplyRotAxisBlock() ;
// calcolo la maschera di corrispondenza tra utensili e fori
if ( ! CalcMask( vHoles, vTools, nMainToolInd, vtTool, vtAux))
if ( ! CalcMask( vHoles, vTools, bFixed, nMainToolInd, vtTool, vtAux))
return false ;
#if ENABLE_DEBUG_MULTIHEAD_HOLES
// Matrice ( #Configurazioni, #Fori )
// Ogni cella contiene ( Indice Foro in cui inserire il tool Main, Indice del Tool che lavoro il foro corrente, vtAux )
// Esempio ( Cella )_ij = ( A, B, vtAux)_ij :
// Nella configurazione i-esima il foro j esimo è lavorato dal tool B inserendo il tool principale nel foro A
// mantenendo un vettore ausiliario pari a vtAux
int nSpace = 25 ;
// riga dei fori
string sHoleRow = " " ; // 10 spazi
for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) {
sHoleRow.append( "(" + ToString( i) + ")") ;
for ( int j = sHoleRow.length() ; j < ( i + 1) * nSpace + 10 ; ++ j)
sHoleRow.append( " ") ;
}
LOG_ERROR( GetEMkLogger(), sHoleRow.c_str()) ;
// scorro le configurazioni
for ( int nC = 0 ; ! vHoles.empty() && nC < int( vHoles[0].vIndTools.size()) ; ++ nC) {
string sRow = "(" + ToString( nC) + ") ->" ;
for ( int j = sRow.length() ; j < 10 ; ++ j)
sRow.append( " ") ;
for ( int nH = 0 ; nH < int( vHoles.size()) ; ++ nH) {
string sCell = "(" ;
if ( vHoles[nH].vIndTools[nC] != IND_TOOL_INVALID &&
vHoles[nH].vToolHole[nC] != IND_TOOL_INVALID &&
vHoles[nH].vVtAux[nC].IsValid()) {
sCell.append( ( ToString( vHoles[nH].vToolHole[nC]) + ", " +
ToString( vHoles[nH].vIndTools[nC]) + ", {" +
ToString( vHoles[nH].vVtAux[nC].x, 3) + ", " +
ToString( vHoles[nH].vVtAux[nC].y, 3) + ", " +
ToString( vHoles[nH].vVtAux[nC].z, 3) + "})").c_str()) ;
}
else
sCell.append( "-, -, {-, -, -})") ;
for ( int j = sCell.length() ; j < nSpace ; ++ j)
sCell.append( " ") ;
sRow.append( sCell) ;
}
LOG_ERROR( GetEMkLogger(), sRow.c_str()) ;
}
#endif
// riduco il numero di configurazioni in base a vtAux
if ( ! KeepMinRotatedConfigs( vHoles, vtAux, vtTool))
return false ;
@@ -1383,63 +1706,74 @@ Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDri
}
dMHOff = dOffMax ;
// Inizio a considerare i fori che presentano meno configurazioni per essere lavorati.
// Essi sono i più critici, quindi vengono gestiti per primi, scremando quindi le configurazioni degli altri.
// Parto ad analizzare i fori lavorabili con una sola possibile configurazione
// se testa fissa
if ( bFixed) {
// Inizio a considerare i fori che presentano meno configurazioni per essere lavorati.
// Essi sono i più critici, quindi vengono gestiti per primi, scremando quindi le configurazioni degli altri.
// Parto ad analizzare i fori lavorabili con una sola possibile configurazione
// cerco le configurazioni di base ( quelle con 1 o due configurazioni opposte)
for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) {
// se foro già lavorato passo al successivo
if ( vHoles[i].bDrill)
continue ;
// se il foro i-esimo non è base, passo al successivo
int nValidConfig ;
bool bBaseCase ;
if ( ! CheckBasedConfig( vHoles, i, nValidConfig, bBaseCase))
// cerco le configurazioni di base ( quelle con 1 o due configurazioni opposte)
for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) {
// se foro già lavorato passo al successivo
if ( vHoles[i].bDrill)
continue ;
// se il foro i-esimo non è base, passo al successivo
int nValidConfig ;
bool bBaseCase ;
if ( ! CheckBasedConfig( vHoles, i, nValidConfig, bBaseCase))
return false ;
if ( ! bBaseCase)
continue ;
// salvo gli indici dei fori ( non ancora lavorati) che vengono lavorati con la sola configurazione presente
if ( ! GetHoleBestConfig( vHoles, i, tabDrills, vtAux, vtTool, nOkHole))
return false ;
}
// se nessun foro lavorabile, esco ( fino a prova contraria non esco mai...)
if ( tabDrills.empty())
return false ;
if ( ! bBaseCase)
continue ;
// salvo gli indici dei fori ( non ancora lavorati) che vengono lavorati con la sola configurazione presente
if ( ! GetHoleBestConfig( vHoles, i, tabDrills, vtAux, vtTool, nOkHole))
// Una volta scremate le configurazioni critiche, cerco i fori non lavorati più vicini ad essi.
// L'idea è che avendo lavorato i fori a signola configurazione, ottengo meno combinazioni
// per i fori ad esso adiacenti... l'idea si ripete per tutti i fori successivi
// per vicinanza cerco gli altri fori oltre ai casi base
while ( nOkHole < int( vHoles.size()) - nUndrilleds) {
INTVECTOR vNextInds ;
if ( ! GetClosestHolesToHole( vHoles, tabDrills.back().nInd_id_hole, false, vNextInds) ||
vNextInds.empty() ||
! GetHoleBestConfig( vHoles, vNextInds[0], tabDrills, vtAux, vtTool, nOkHole))
return false ;
}
// per sicurezza ...
if ( tabDrills.empty())
return false ;
// Analizzando i fori in base alle possibili combinazioni, ho riempito la tabella delle forature
// multiple con lavorazioni sparse tra loro, riordino quindi le discese degli utensili in base
// alla vicinanza dei fori lavorati dal Tool principale
if ( ! MultiHeadOrderConfig( tabDrills, vHoles, vtTool, vtAux))
return false ;
}
// se nessun foro lavorabile, esco ( fino a prova contraria non esco mai...)
if ( tabDrills.empty())
return false ;
// Una volta scremate le configurazioni critiche, cerco i fori non lavorati più vicini ad essi.
// L'idea è che avendo lavorato i fori a signola configurazione, ottengo meno combinazioni
// per i fori ad esso adiacenti... l'idea si ripete per tutti i fori successivi
// per vicinanza cerco gli altri fori oltre ai casi base
while ( nOkHole < int( vHoles.size()) - nUndrilleds) {
INTVECTOR vNextInds ;
if ( ! GetClosestHolesToHole( vHoles, tabDrills.back().nInd_id_hole, false, vNextInds) ||
vNextInds.empty() ||
! GetHoleBestConfig( vHoles, vNextInds[0], tabDrills, vtAux, vtTool, nOkHole))
return false ;
// se utensili selezionabili
else {
// Inizio a considerare le configurazioni che presentano più utensili attivi, decrementando
// con il numero di passsate gli utensili selezionati
if ( ! OrderConfigsForSelectableTools( vHoles, vTools, nMainToolInd, tabDrills))
return false ;
}
// per sicurezza ...
if ( tabDrills.empty())
return false ;
// Analizzando i fori in base alle possibili combinazioni, ho riempito la tabella delle forature
// multiple con lavorazioni sparse tra loro, riordino quindi le discese degli utensili in base
// alla vicinanza dei fori lavorati dal Tool principale
if ( ! MultiHeadOrderConfig( tabDrills, vHoles, vtTool, vtAux))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, const Vector3d& vtTool,
const Vector3d& vtAux)
Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, bool bFixed, int nIndMT,
const Vector3d& vtTool, const Vector3d& vtAux)
{
/*
funzione per il calcolo della maschera di compatibilità tra un insieme di utensili e
un insieme di fori
un insieme di fori.
bFixed indica se i tool sono attivabili o meno
*/
// controllo dei parametri
@@ -1467,9 +1801,10 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co
Hole Hole_i = vHoles[i].hole ;
if ( ! MultiHeadVerifyHole( Hole_i, vTools[nIndMT].pTool, dDiamToler, m_vId[vHoles[i].nIndInSelVector]))
continue ;
// angoli per allineare versore T del tool principale con vtDir del foro i-esimo
int nStat ;
DBLVECTOR vAng1, vAng2 ;
// angoli per allineare versore T del tool principale con vtDir del foro i-esimo
if ( ! m_pMchMgr->GetCalcAngles( Hole_i.vtDir, V_NULL, nStat, vAng1, vAng2))
continue ;
Vector3d vtTnew ;
@@ -1484,7 +1819,7 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co
vtAnew = vtAux ;
// creo un nuovo sistema di riferimento centrato nel Tool principale
Frame3d frMT ;
Frame3d frMT ;
frMT.Set( vTools[nIndMT].ptToolTip, vtTool, vtAux) ;
if ( ! frMT.IsValid())
return false ;
@@ -1501,9 +1836,35 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co
// controllo la compatibilità tra le geometrie dei Tool e dei fori
CheckOtherHolesWithTools( vHoles, vTools, nIndMT, i, Hole_i, frMT, frHMT, dDiamToler, nDrills) ;
// controllo quanti fori sono riuscito a lavorare e setto i loro parametri di foratura
if ( nDrills == nExitCnt - nNullTools) { // se ho lavorato il numero corretto di fori ...
// se utensili non selezionabili
if ( bFixed) {
// controllo quanti fori sono riuscito a lavorare e setto i loro parametri di foratura
if ( nDrills == nExitCnt - nNullTools) { // se ho lavorato il numero corretto di fori ...
for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD) {
if ( vHoles[nD].bTempDrill) {
vHoles[nD].vToolHole.push_back( i) ; // indice del foro per il tool principale
vHoles[nD].vIndTools.push_back( vHoles[nD].nTempTool) ; // indice del tool che lavora questo foro
vHoles[nD].vVtAux.push_back( frHMT.VersX()) ; // versore ausiliario A del tool principale
}
else {
// rendo tutto non valido
vHoles[nD].vToolHole.push_back( IND_TOOL_INVALID) ;
vHoles[nD].vIndTools.push_back( IND_TOOL_INVALID) ;
vHoles[nD].vVtAux.push_back( V_INVALID) ;
}
}
}
else {
for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD)
vHoles[nD].bTempDrill = false ;
}
}
// se utensili selezionabili
else {
// memorizzo la configurazione attuale
for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD) {
// se il foro è lavorabile, memorizzo la configurazione
if ( vHoles[nD].bTempDrill) {
vHoles[nD].vToolHole.push_back( i) ; // indice del foro per il tool principale
vHoles[nD].vIndTools.push_back( vHoles[nD].nTempTool) ; // indice del tool che lavora questo foro
@@ -1517,10 +1878,6 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co
}
}
}
else {
for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD)
vHoles[nD].bTempDrill = false ;
}
// se la testa può ruotare
if ( nStat < 0) {
@@ -1567,9 +1924,33 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co
// setto le variabili temporanee per il foro i-esimo
vHoles[i].bTempDrill = true ;
vHoles[i].nTempTool = nIndMT ;
// controllo quanti fori sono riuscito a lavorare in questo nuovo sistema di riferimento
if ( nDrills == nExitCnt - nNullTools) {
// se utensili non selezionabili
if ( bFixed) {
// controllo quanti fori sono riuscito a lavorare in questo nuovo sistema di riferimento
if ( nDrills == nExitCnt - nNullTools) {
for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD) {
if ( vHoles[nD].bTempDrill) {
vHoles[nD].vToolHole.push_back( i) ; // indice del foro per il tool principale
vHoles[nD].vIndTools.push_back( vHoles[nD].nTempTool) ; // indice del tool che lavora questo foro
vHoles[nD].vVtAux.push_back( frHMT.VersX()) ; // versore ausiliario del tool principale
}
else {
// rendo tutto non valido
vHoles[nD].vToolHole.push_back( IND_TOOL_INVALID) ;
vHoles[nD].vIndTools.push_back( IND_TOOL_INVALID) ;
vHoles[nD].vVtAux.push_back( V_INVALID) ;
}
}
}
else {
for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD)
vHoles[nD].bTempDrill = false ;
}
}
// se utensili selezionabili
else {
// memorizzo la configurazione attuale
for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD) {
if ( vHoles[nD].bTempDrill) {
vHoles[nD].vToolHole.push_back( i) ; // indice del foro per il tool principale
@@ -1584,10 +1965,6 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co
}
}
}
else {
for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD)
vHoles[nD].bTempDrill = false ;
}
}
}
}
@@ -1619,7 +1996,7 @@ Drilling::CheckOtherHolesWithTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools
nDrills < 0 || nDrills > max( int( vHoles.size()), int( vTools.size())))
return false ;
// definisco il punto dove cade il tool principale
// definisco il punto dove cade il tool principale
Hole holeTM = holeICP ; // copia del foro i-esimo
// ciclo su tutti i tools
+6 -3
View File
@@ -87,20 +87,23 @@ class Drilling : public Machining
bool VerifyHoleFromBottom( const Hole& hole, SelData Id) ;
bool DoStandardDrilling( const Hole& hole, SelData Id, int nPathId, double nMHOff, const Vector3d& vtA) ;
bool DoPeckDrilling( const Hole& hole, SelData Id, int nPathId, double dMHOff, const Vector3d& vtA) ;
bool MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& vDrills, double& dMHOff) ;
bool CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, const Vector3d& vtTool, const Vector3d& vtAux) ;
bool MultiHeadDrilling( const SELVECTOR& vId, int nClId, bool bFixed, TABMHDRILL& vDrills, double& dMHOff) ;
bool CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, bool bFixed, int nIndMT, const Vector3d& vtTool, const Vector3d& vtAux) ;
bool CalcDrilledHolesByConfig( VECTORHOLE& vHoles, int nMyInd, int nIndConfig, INTVECTOR& vIndDrilled) ;
bool EraseDuplicatedConfigs( VECTORHOLE& vHoles) ;
bool KeepMinRotatedConfigs( VECTORHOLE& vHoles, const Vector3d vtAux, const Vector3d vtTool) ;
bool CalcMultyHeadUndrilledHoles( const VECTORHOLE& vHoles, INTVECTOR& vIdUndrilledHoles) ;
bool CheckBasedConfig( const VECTORHOLE& vHoles, int nIndHole, int& nValidConfig, bool& bBaseCase) ;
bool GetClosestHolesToHole( const VECTORHOLE& vHoles, int nMyInd, bool bDrilled, INTVECTOR& vInds) ;
bool OrderConfigsForSelectableTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndToolMain, TABMHDRILL& vDrills) ;
bool GetConfigsWithMoreDrilledHoles( const VECTORHOLE& vHoles, INTVECTOR& vInds) ;
bool ChooseBestConfigForSelectableTools( const VECTORHOLE& vHoles, int nIndToolMain, INTVECTOR& vConfInds, int& nBestConf) ;
bool CheckOtherHolesWithTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndTM, int nIndHTM, Hole holeICP,
const Frame3d& frHTM, const Frame3d& frHMTOP, double dDiamToler, int& nDrills) ;
bool GetHoleBestConfig( VECTORHOLE& vHoles, int nInd, TABMHDRILL& tabDrills, const Vector3d& vtAux, const Vector3d& vtTool, int& nOkHole) ;
bool MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamToler, SelData Id) ;
bool MultiHeadOrderConfig( TABMHDRILL& tabDrills, const VECTORHOLE& vHoles, const Vector3d& vtTool, const Vector3d& vtAux) ;
bool VerifyMultiParallelFixedDrills( void) ;
int VerifyMultiParallelFixedDrills( void) ;
private :
double GetSpeed() const