Merge commit '5d77408018aa0c4088577770e8bca60d24cfe833'
This commit is contained in:
+471
-94
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user