EgtMachKernel :

- Fori con più tools.
This commit is contained in:
Riccardo Elitropi
2023-02-16 15:11:47 +01:00
parent 15931dc304
commit 0e8c41192d
2 changed files with 573 additions and 22 deletions
+559 -19
View File
@@ -19,6 +19,7 @@
#include "OperationConst.h"
#include "/EgtDev/Include/EXeCmdLogOff.h"
#include "/EgtDev/Include/EGkGeoPoint3d.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
#include "/EgtDev/Include/EGkCurveLine.h"
#include "/EgtDev/Include/EGkCurveArc.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
@@ -27,6 +28,7 @@
#include "/EgtDev/Include/EGkUserObjFactory.h"
#include "/EgtDev/Include/EGnStringKeyVal.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include "/EgtDev/Include/EGkGeoFrame3d.h"
using namespace std ;
@@ -68,6 +70,35 @@ struct Hole
: nOriId( GDB_ID_NULL), ptIni(), vtDir(), dDiam( 0), dThick( 0), dLen( 0), bBlind( true) {}
} ;
struct MHDrill {
int nInd_id_hole ; // indice id foro
Vector3d vtAux ; // vettore ausiliario per tale foratura
} ;
struct HoleInfo {
Hole hole ; // foro
bool bDrill = false ; // se alla fine verrà svuotato
bool bTempDrill = false ; // per test maschera (se durante un test viene svuotato o no)
int nTempTool = -1 ; // per test maschera ( indice utensile che lo svuota durante un test)
bool bSkipToAngle = false ; // nel caso di più assi rotanti, se foro già svuotato con testa orientata
bool bForToolM = false ; // se tool main svuoterà questo foro
int nIndHoleToolM = -1 ; // indice del foro che lo svuoterà inserendo il primo tool in esso
INTVECTOR vToolHole ; // vettore di indici dei fori ai quali inserire l'ultim punta per lavorare il foro corrente
INTVECTOR vIndTools ; // vettore dei tool associati ad ogni svuotatura in vToolHole (ordinati)
VCT3DVECTOR vVtAux ; // vettore dei vtAux ausiliari del tool principale per svuotare questo foro (ordinati)
int nIndTool = -1 ; // indice del tool che alla fine svuoterà il foro
Vector3d vtAux ; // vettore ausiliario del tool principale che permette al tool principale di svuotare questo foro
Point3d ptBtn ; // punto interno alla base del foro
int nIndInSelVector = 0 ; // indice nel vettore m_vId (id fori selezionati)
} ;
struct ToolInfo
{
ToolData* pTool ; // 1) puntatore per utensile (nullo se utensile non presente)
Point3d ptETool ; // 2) punto finale del tool (per ptBtn del foro)
} ;
//----------------------------------------------------------------------------
USEROBJ_REGISTER( GetOperationClass( OPER_DRILLING), Drilling) ;
@@ -450,16 +481,16 @@ Drilling::SetGeometry( const SELVECTOR& vIds)
// se lavorazione standard
if ( m_Params.m_nSubType == DRI_SUB_STD) {
// recupero il valore di tolleranza sul diametro
double dDiamTol = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
//double dDiamTol = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
// verifico che gli identificativi rappresentino dei fori con il corretto diametro
for ( int i = 0 ; i < int( vIds.size()) ; ++ i) {
// recupero i dati del foro
Hole hole ;
if ( ! GetHoleData( vIds[i], hole) || ! VerifyDiameter( hole.dDiam, m_TParams.m_dDiam, dDiamTol)) {
string sInfo = "Warning in Drilling : Skipped entity " + ToString( vIds[i].nId) ;
m_pMchMgr->SetWarning( 2151, sInfo) ;
continue ;
}
//Hole hole ;
//if ( ! GetHoleData( vIds[i], hole) || !VerifyDiameter(hole.dDiam, m_TParams.m_dDiam, dDiamTol)) {
// string sInfo = "Warning in Drilling : Skipped entity " + ToString( vIds[i].nId) ;
// m_pMchMgr->SetWarning( 2151, sInfo) ;
// continue ;
//}
// posso aggiungere alla lista
m_vId.push_back( vIds[i]) ;
}
@@ -513,7 +544,7 @@ Drilling::Preview( bool bRecalc)
// se lavorazione standard
if ( m_Params.m_nSubType == DRI_SUB_STD)
return StdandardProcess( bRecalc, nPvId, GDB_ID_NULL) ;
return StandardProcess( bRecalc, nPvId, GDB_ID_NULL) ;
// se altrimenti lavorazione lungo curve
else if ( m_Params.m_nSubType == DRI_SUB_ALONG_CURVE)
return AlongCurveProcess( bRecalc, nPvId, GDB_ID_NULL) ;
@@ -571,7 +602,7 @@ Drilling::Apply( bool bRecalc, bool bPostApply)
// se lavorazione standard
if ( m_Params.m_nSubType == DRI_SUB_STD) {
if ( ! StdandardProcess( bRecalc, GDB_ID_NULL, nClId))
if ( ! StandardProcess( bRecalc, GDB_ID_NULL, nClId))
return false ;
}
// se altrimenti lavorazione lungo curve
@@ -658,10 +689,42 @@ Drilling::Update( bool bPostApply)
//----------------------------------------------------------------------------
bool
Drilling::StdandardProcess( bool bRecalc, int nPvId, int nClId)
Drilling::StandardProcess( bool bRecalc, int nPvId, int nClId)
{
// elaboro i singoli fori
// controllo se ho più uscite
string sCurrHead ;
if ( ! m_pMchMgr->GetCurrMachine()->GetCurrHead( sCurrHead))
return false ;
int nExit = m_pMchMgr->GetCurrMachine()->GetHeadExitCount( sCurrHead) ;
TABMHDRILL tabDrills ;
double dMHOff = 0 ;
// se ho più uscite...
if ( nExit > 1) {
if ( ! MultiHeadDrilling( nExit, m_vId, nClId, tabDrills, dMHOff))
return false ;
if( tabDrills.size() == 0)
return true ;
int j = 0 ;
for ( int i = 0 ; i < ( int)tabDrills.size() ; ++i) {
// se richiesto preview
if ( nPvId != GDB_ID_NULL) {
if ( ! GenerateHolePv( j, m_vId[tabDrills[i][0].nInd_id_hole], MCH_PATH, nClId))
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( j, m_vId[tabDrills[i][0].nInd_id_hole], MCH_PATH, nClId, dMHOff, tabDrills[i][0].vtAux))
return false ;
}
// incremento indice
++j ;
}
return true ;
}
// ... altrimenti elaboro i singoli fori
int i = 0 ;
for ( const auto& vId : m_vId) {
// se richiesto preview
@@ -678,12 +741,487 @@ Drilling::StdandardProcess( bool bRecalc, int nPvId, int nClId)
return false ;
}
// incremento indice
++ i ;
++i ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::MultiHeadDrilling( int nExit, const SELVECTOR& vId, int nClId, TABMHDRILL& tabDrills, double& dMHOff, bool bOrd) {
// controllo parametri
tabDrills.clear() ;
if (( int)vId.size() == 0)
return true ;
// recupero il nome della testa
string sHead ;
m_pMchMgr->GetCurrMachine()->GetCurrHead( sHead) ;
// gestore dei tool corrente
ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ;
// ------------------------------ Tools ------------------------------------------
// ciclo tutti i tools salvando le loro geometrie
typedef vector<ToolInfo> VECTORTOOL ;
VECTORTOOL vTools ; vTools.reserve( nExit) ;
int nNullTools = 0 ; // numero di utensili non attivi
int nIndMainTool = 0 ; // Main Tool ( non nullo )
bool bToolValid = false ; // se il Tool attuale è valido ( non nullo )
for ( int t = 0 ; t < nExit ; ++t) { // recupero l'utensile sulle uscite
string sToolName ;
ToolInfo TInf ;
if( ! m_pMchMgr->GetLoadedTool( sHead, t + 1, sToolName) || sToolName.empty()) {
TInf.pTool = nullptr ; // se non attivo ( nullo )
vTools.push_back( TInf) ;
++nNullTools ;
continue ;
}
// se attivo ( non nullo )
TInf.pTool = (( ToolData*)pTMgr->GetTool( sToolName)) ;
vTools.push_back( TInf) ;
// imposto il tool di riferimento come il tool m_TParams
if( TInf.pTool->m_Uuid == m_TParams.m_Uuid)
nIndMainTool = t ;
}
if ( nNullTools == nExit || vTools.size() == 0) // se non ho utensili attivi o validi...
return false ;
Point3d PtEndTool ; // punto finale del tool
Vector3d vtDirPrec, vtDirAct, vtAux ; // per controllare direzioni dei tool ( T )
Vector3d vtT, vtA ; // versore T e A per sistema di riferimento del tool
bToolValid = false ;
for ( int t = 0 ; t < nExit ; ++t) { // controllo direzioni ( T ) e punto finale all'estremità
if ( vTools[t].pTool == nullptr)
continue ;
m_pMchMgr->GetCurrMachine()->GetHeadExitPosDirAux( sHead, t + 1, PtEndTool, vtDirAct, vtAux) ;
if ( ! bToolValid) {
bToolValid = true ;
vtDirPrec = vtDirAct ;
}
else {
// controllo che le direzioni dei tool siano tutte parallele tra loro
if ( ! AreSameVectorApprox( vtDirAct, vtDirPrec))
return false ;
}
if ( t == nIndMainTool) { // per il sistema di riferiemento centrato sul tool principale
vtT = vtDirAct ;
vtA = vtAux ;
}
PtEndTool.Translate( - vtDirAct * ( vTools[t].pTool->m_dLen)) ;
vTools[t].ptETool = PtEndTool ;
}
// ------------------------------ Holes ------------------------------------------
// ciclo tutti i fori salvando le loro geometrie
typedef vector<HoleInfo> VECTORHOLE ;
VECTORHOLE vHoles(( int)vId.size()) ; // vettore dei fori
bool bOKHole = false ; // validità di almeno un foro
for ( int h = 0 ; h < ( int)vId.size() ; ++h) {
Hole hole ;
if ( ! GetHoleData( m_vId[h], hole)) {
string sInfo = "Warning in Drilling : Skipped entity " + ToString( m_vId[h]) ;
m_pMchMgr->SetWarning( 2151, sInfo) ;
continue ;
}
// se richiesta inversione e foro passante, provvedo
if ( m_Params.m_bInvert) {
if ( hole.bBlind) {
m_pMchMgr->SetLastError( 2114, "Error in Drilling : blind hole not reversible") ;
return false ;
}
else {
hole.ptIni -= hole.vtDir * hole.dThick ;
hole.vtDir.Invert() ;
}
}
// se lavorazione del foro non arriva al suo fondo, lo considero cieco
if ( hole.dLen < hole.dThick - 10 * EPS_SMALL)
hole.bBlind = true ;
vHoles[h].hole = hole ;
vHoles[h].nIndInSelVector = h ;
bOKHole = true ;
}
if ( vHoles.size() == 0 || ! bOKHole) // se non ho fori...
return true ;
// calcolo la maschera tra tools e holes
if( ! CalcMask( vHoles, vTools, nIndMainTool, vtT, vtA))
return false ;
// i fori con dimensione 0 del vettore vToolHole non possono essere svuotati
int nNoDrillHoles = 0 ;
for ( int i = 0 ; i < ( int)vHoles.size() ; ++i) {
if ( vHoles[i].vToolHole.size() == 0)
++nNoDrillHoles ;
}
// resetto le variabili di controllo di svuotatura temporanea per tutti i fori
for ( int k = 0 ; k < ( int)vHoles.size() ; ++k)
vHoles[k].bTempDrill = false ;
// numero di fori svuotati
int nOkHole = 0 ;
// decido in quali fori inserire il tool principale
for ( int nCheck = 1 ; nCheck < ( int)vHoles.size() && nOkHole < ( int)vHoles.size() - nNoDrillHoles ; ++nCheck) {
for ( int i = 0 ; i < ( int)vHoles.size() ; ++i) {
if ( vHoles[i].vToolHole.size() == nCheck && ! vHoles[i].bDrill) { // prendo tutti i fori con vToolHope di lunghezza nCheck non già svuotati
vHoles[vHoles[i].vToolHole[0]].bForToolM = true ;
vHoles[vHoles[i].vToolHole[0]].nIndTool = nIndMainTool ;
vHoles[vHoles[i].vToolHole[0]].nIndHoleToolM = vHoles[i].vToolHole[0] ;
vHoles[vHoles[i].vToolHole[0]].vtAux = vHoles[i].vVtAux[0] ;
for ( int k = 0 ; k < ( int)vHoles.size() ; ++k) {
for( int l = 0 ; l < ( int)vHoles[k].vToolHole.size() ; ++l) {
if ( vHoles[k].vToolHole[l] == vHoles[i].vToolHole[0] && ! vHoles[k].bDrill) {
vHoles[k].bDrill = true ;
vHoles[k].nIndTool = vHoles[k].vIndTools[0] ;
vHoles[k].nIndHoleToolM = vHoles[vHoles[i].vToolHole[0]].nIndHoleToolM ;
vHoles[k].vtAux = vHoles[k].vVtAux[l] ;
++nOkHole ;
break ;
}
}
}
}
}
}
// calcolo la massima differenza di lunghezza tra il primo tool e gli altri ( così l'elevazione finale rimane compatibile)
double dRefLen = vTools[nIndMainTool].pTool->m_dTLen ;
double dOffMax = 0 ;
for ( int t = 0 ; t < ( int)vTools.size() && nNoDrillHoles != (int)vHoles.size() ; ++t) {
if ( vTools[t].pTool == nullptr || t == nIndMainTool)
continue ;
if ( vTools[t].pTool->m_dTLen > dRefLen + dOffMax) {
dOffMax = vTools[t].pTool->m_dTLen - dRefLen ;
}
}
dMHOff = dOffMax ;
// riempio la maschera
VCT3DVECTOR vVtA ;
for ( int i = 0 ; i < ( int)vHoles.size() && nNoDrillHoles != ( int)vHoles.size() ; ++i) {
if ( ! vHoles[i].bForToolM)
continue ;
// per tutti i fori che vengono svuotati da un tool t-esimo conto quanti versori A diversi tra loro trovo
for( int j = 0 ; j < ( int)vHoles.size() ; ++j) {
if ( vHoles[j].nIndHoleToolM != i)
continue ;
if (( int)vVtA.size() == 0)
vVtA.push_back( vHoles[j].vtAux) ;
else {
bool bPush = true ;
for( int v = 0 ; v < ( int)vVtA.size() ; ++v )
if( AreSameVectorApprox( vHoles[j].vtAux, vVtA[v])) {
bPush = false ;
break ;
}
if( bPush)
vVtA.push_back( vHoles[j].vtAux) ;
}
}
for( int v = 0 ; v < ( int)vVtA.size() ; ++v) {
vector<MHDrill> vRowDrill ;
MHDrill FirstMHDrill ;
FirstMHDrill.nInd_id_hole = i ;
FirstMHDrill.vtAux = vVtA[v] ;
vRowDrill.push_back( FirstMHDrill) ;
tabDrills.push_back( vRowDrill) ;
}
vVtA.clear() ;
}
if ( tabDrills.size() == 0) // se non trovo corrispondenze ...
return true ;
// se devo riordinare
if ( bOrd) {
struct Order
{
int nInd_id_hole ;
Point3d ptIni ;
} ;
typedef vector<Order> VECTORORDER ;
VECTORORDER vOrder ;
for ( int i = 0 ; i < ( int)tabDrills.size() ; ++i) {
Order newOrder ;
newOrder.nInd_id_hole = tabDrills[i][0].nInd_id_hole ;
newOrder.ptIni = vHoles[tabDrills[i][0].nInd_id_hole].hole.ptIni ;
vOrder.push_back( newOrder) ;
}
// prendo come riferimento il punto del primo foro selezionato dall'utente
Point3d ptRef = vOrder[0].ptIni ;
double dMinDist = INFINITO ;
int nIndexSwitch = -1 ;
for ( int i = 0 ; i < ( int)vOrder.size() - 1 ; ++i) {
for ( int j = i + 1 ; j < ( int)vOrder.size() ; ++j) {
Point3d ptS = vOrder[j].ptIni ;
if ( Dist( ptS, ptRef) < dMinDist) {
dMinDist = Dist( ptS, ptRef) ;
nIndexSwitch = j ;
}
}
if ( nIndexSwitch != i + 1) {
vector<MHDrill> VHelp = tabDrills[nIndexSwitch] ;
tabDrills[nIndexSwitch] = tabDrills[i + 1] ;
tabDrills[i + 1] = VHelp ;
}
ptRef = vOrder[i + 1].ptIni ;
dMinDist = INFINITO ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::CalcMask( VECTORHOLE& vHoles, VECTORTOOL& vTools, int nIndMT, Vector3d vtT, Vector3d vtA) {
// recupero il valore di tolleranza sul diametro
double dDiamTol = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
// controllo dei parametri
if (( int)vHoles.size() <= 0 || ( int)vTools.size() <= 0)
return false ;
int nExit = ( int)vTools.size() ;
int nNullTools = 0 ;
for( int i = 0 ; i < ( int)vTools.size() ; ++i){
if( vTools[i].pTool == nullptr)
++nNullTools ;
}
// in ogni foro i-esimo inserisco il Tool principale
for( int i = 0 ; i < ( int)vHoles.size() ; ++i){
// resetto le veriabili di controllo di svuotatura temporanea per tutti i fori
for ( int k = 0 ; k < ( int)vHoles.size() ; ++k) {
vHoles[k].bTempDrill = false ;
vHoles[k].nTempTool = -1 ;
}
// verifica validità del foro i-esimo per il Tool principale
Hole Hole_i = vHoles[i].hole ;
if ( ! MultiHeadVerifyHole( Hole_i, vTools[nIndMT].pTool, dDiamTol, m_vId[vHoles[i].nIndInSelVector]))
continue ;
int nStat ;
DBLVECTOR vAng1, vAng2 ;
// angoli per allineare 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 ;
// check che T sia allineato con vtDir
if ( ! m_pMchMgr->GetCalcToolDirFromAngles( vAng1, vtTnew) || ! AreSameVectorApprox( vtTnew, Hole_i.vtDir))
continue ;
Vector3d vtAnew ;
// nuova configurazione del versore A ottenuta
if ( ! m_pMchMgr->GetCalcAuxDirFromAngles( vAng1, vtAnew))
continue ;
// creo un nuovo sistema di riferimento centrato nel Tool principale
Frame3d frMT ;
frMT.Set( vTools[nIndMT].ptETool, vtT, vtA) ;
if( ! frMT.IsValid())
return false ;
// creo un frame nel foro i-esimo orientato come il frame sul tool principale ( origine nella base interna del foro)
Frame3d frHMT ;
frHMT.Set( Hole_i.ptIni - Hole_i.vtDir * Hole_i.dLen, vtTnew, vtAnew) ;
if( ! frHMT.IsValid())
return false ;
// numero di svuotature inserendo il Tool principale nel foro i-esimo
int nDrills = 1 ;
// setto le variabili temporanee per il foro i-esimo
vHoles[i].bTempDrill = true ;
vHoles[i].nTempTool = nIndMT ;
// controllo la compatibilità tra le geometrie dei Tool e dei fori
CheckOtherHolesWithTools( vHoles, vTools, nIndMT, i, Hole_i, frMT, frHMT, dDiamTol, nDrills) ;
// controllo quanti fori sono riuscito a svuotare e setto i loro parametri di foratura
if ( nDrills == nExit - nNullTools) { // se ho svuotato il numero corretto di fori ...
for ( int d = 0 ; d < ( int)vHoles.size() ; ++d) {
if ( vHoles[d].bTempDrill) {
vHoles[d].vToolHole.push_back( i) ; // indice del foro per il tool principale
vHoles[d].vIndTools.push_back( vHoles[d].nTempTool) ; // indice del tool che svuota questo foro
vHoles[d].vVtAux.push_back( frHMT.VersX()) ; // versore ausiliario A del tool principale
}
}
}
else {
for( int d = 0 ; d < ( int)vHoles.size() ; ++d)
if( vHoles[d].bTempDrill)
vHoles[d].bTempDrill = false ;
}
if ( nStat < 0) { // se la testa può ruotare
// inizio a scorrere tutti i tools
for ( int t = 0 ; t < ( int)vTools.size() ; ++t) {
if ( vTools[t].pTool == nullptr || t == nIndMT)
continue ;
// cerco se ho un foro j-esimo adatto per quella punta
for ( int j = 0 ; j < ( int)vHoles.size() ; ++j) {
Hole Hole_j = vHoles[j].hole ;
if ( i == j
|| vHoles[j].bSkipToAngle
|| ! AreSameVectorApprox( Hole_j.vtDir, Hole_i.vtDir)
|| ! MultiHeadVerifyHole( Hole_j, vTools[t].pTool, dDiamTol, m_vId[vHoles[j].nIndInSelVector]))
continue ;
// resetto le veriabili di controllo di svuotatura temporanea per tutti i fori
for ( int k = 0 ; k < ( int)vHoles.size() ; ++k) {
vHoles[k].bTempDrill = false ;
vHoles[k].nTempTool = -1 ;
}
Vector3d vtRefT = vTools[t].ptETool - vTools[nIndMT].ptETool ;
Vector3d vtRefH = Hole_j.ptIni - Hole_j.vtDir * Hole_j.dLen -
( Hole_i.ptIni - Hole_i.vtDir * Hole_i.dLen) ;
if(( vtRefH.Len() - vtRefT.Len()) < EPS_SMALL) { // se le distanze sono compatibili
// rioriento il frame sul foro i-esimo
Point3d ptHj = Hole_j.ptIni - Hole_j.vtDir * Hole_j.dLen ;
ptHj.ToLoc( frHMT) ;
Vector3d vtProjB( ptHj.x, ptHj.y, 0) ;
Point3d ptTt = vTools[t].ptETool ;
ptTt.ToLoc( frMT) ;
Vector3d vtProjA( ptTt.x, ptTt.y, 0) ;
double dAngle ; vtProjA.GetAngle( vtProjB, dAngle) ;
frHMT.Rotate( frHMT.Orig(), frHMT.VersZ(), dAngle) ;
nDrills = 1 ; // foratura nel foro i-esimo e j-esimo
CheckOtherHolesWithTools( vHoles, vTools, nIndMT, i, Hole_i, frMT, frHMT, dDiamTol, nDrills) ;
// setto le variabili temporanee per il foro i-esimo
vHoles[i].bTempDrill = true ;
vHoles[i].nTempTool = nIndMT ;
// controllo quanti fori sono riuscito a svuotare in questo nuovo sistema di riferimento
if ( nDrills == nExit - nNullTools) {
for ( int d = 0 ; d < ( int)vHoles.size() ; ++d) {
if ( vHoles[d].bTempDrill) {
vHoles[d].vToolHole.push_back( i) ; // indice del foro per il tool principale
vHoles[d].vIndTools.push_back( vHoles[d].nTempTool) ; // indice del tool che svuota questo foro
vHoles[d].vVtAux.push_back( frHMT.VersX()) ; // versore ausiliario del tool principale
vHoles[d].bSkipToAngle = true ;
}
}
}
else {
for( int d = 0 ; d < ( int)vHoles.size() ; ++d)
if( vHoles[d].bTempDrill)
vHoles[d].bTempDrill = false ;
}
}
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::CheckOtherHolesWithTools( VECTORHOLE& vHoles, VECTORTOOL& vTools, int nIndTM, int nIndHTM, Hole holeICP, Frame3d frMT,
Frame3d frHMT, double dDiamTol, int& nDrills) {
// controllo parametri
if(( int)vHoles.size() < 1 || vTools.size() < 1)
return true ;
if( nIndTM >= ( int)vTools.size() || nIndTM < 0
|| nIndHTM >= ( int)vHoles.size() || nIndHTM < 0
|| ! frMT.IsValid() || ! frHMT.IsValid()
|| nDrills < 0 || nDrills > max(( int)vHoles.size(), ( int)vTools.size()))
return false ;
// definisco il punto dove cade il tool principale
Hole holeTM = holeICP ; // copia del foro i-esimo
// ciclo su tutti i tools
for ( int t = 0 ; t < ( int)vTools.size() ; ++t) {
if ( vTools[t].pTool == nullptr || t == nIndTM)
continue ;
// esprimo il punto finale del tool t-esimo nel sistema di riferimento del Tool principale
Point3d ptETt = vTools[t].ptETool ;
ptETt.ToLoc( frMT) ;
// cerco se ho un foro j-esimo adatto per quella punta
for ( int j = 0 ; j < ( int)vHoles.size() ; ++j) {
Hole Hole_j = vHoles[j].hole ; // copia del foro j-esimo
// controllo che il foro j-esimo non sia l'i-esimo, che non sia stato già precedentemente svuotato da un altro tool t'-esimo ...
// ... che vtDir del foro i-esimo coincida con vtDir del foro j-esimo e che il tool t-esimo sia compatibile con il foro j-esimo
if ( nIndHTM == j
|| vHoles[j].bTempDrill
|| ! AreSameVectorApprox( Hole_j.vtDir, holeTM.vtDir)
|| ! MultiHeadVerifyHole( Hole_j, vTools[t].pTool, dDiamTol, m_vId[vHoles[j].nIndInSelVector]))
continue ;
// esprimo il foro j-esimo nel sistema di riferimento del Tool principale centrato nel foro i-esimo
Point3d ptHj = Hole_j.ptIni - Hole_j.vtDir * Hole_j.dLen ;
ptHj.ToLoc( frHMT) ;
// controllo la compatibilità
if ( AreSamePointApprox( ptHj, ptETt)) {
++nDrills ; // un foro in più svuotato
// aggiorno le variabili temporanee
vHoles[j].bTempDrill = true ;
vHoles[j].nTempTool = t ;
break ; // non controllo gli altri vertici per la punta t-esima
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamTol, SelData Id) {
// verifico che il diamtro del tool sia compatibile con quello del foro
if ( ! VerifyDiameter( hole.dDiam, Tool->m_dDiam, dDiamTol))
return false ;
// imposto elevazione da lunghezza foro con possibilità di sovrascrittura da info
double dElev = hole.dLen ;
double dMaxElev ;
if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) {
dElev = dMaxElev ;
hole.ptIni += hole.vtDir * ( dElev - hole.dLen) ;
hole.dLen = dElev ;
}
// limito lunghezza foro a massima lavorazione della punta
double dAddLen = ( hole.bBlind ? 0 : m_Params.m_dThroughAddLen) ;
if (( dElev + dAddLen) > Tool->m_dMaxMat + EPS_SMALL) {
hole.dLen = Tool->m_dMaxMat + max( hole.dLen - dElev, 0.) ;
hole.bBlind = true ;
}
if ( ! VerifyHoleFromBottom( hole, Id))
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
Drilling::AlongCurveProcess( bool bRecalc, int nPvId, int nClId)
@@ -976,12 +1514,12 @@ Drilling::GenerateHolePv( int nInd, const SelData& nCircId, const string& sPName
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
if ( IsNull( pCrvArc) || ! pCrvArc->Set( hole.ptIni, hole.vtDir, 0.5 * m_TParams.m_dDiam))
return false ;
// assegno il versore estrusione e lo spessore
// assegno il versore estrusione e lo spessore
pCrvArc->SetExtrusion( hole.vtDir) ;
pCrvArc->SetThickness( - hole.dLen) ;
// inserisco nel DB
int nDriId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrvArc)) ;
// assegno nome e colore
// assegno nome e colore
m_pGeomDB->SetName( nDriId, MCH_PV_CUT) ;
m_pGeomDB->SetMaterial( nDriId, LIME) ;
// aggiorno numero forature
@@ -991,7 +1529,7 @@ Drilling::GenerateHolePv( int nInd, const SelData& nCircId, const string& sPName
//----------------------------------------------------------------------------
bool
Drilling::GenerateHoleCl( int nInd, const SelData& nCircId, const string& sPName, int nClId)
Drilling::GenerateHoleCl( int nInd, const SelData& nCircId, const string& sPName, int nClId, double dMHOff, Vector3d vtA)
{
// creo gruppo per geometria di lavorazione del foro
int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ;
@@ -1059,7 +1597,7 @@ Drilling::GenerateHoleCl( int nInd, const SelData& nCircId, const string& sPName
// foro normale
if ( m_Params.m_dStep < EPS_SMALL ||
m_Params.m_dStep > hole.dLen - EPS_SMALL) {
if ( DoStandardDrilling( hole, nCircId, nPathId)) {
if ( DoStandardDrilling( hole, nCircId, nPathId, dMHOff, vtA)) {
// aggiorno numero forature
++ m_nDrillings ;
}
@@ -1457,7 +1995,7 @@ Drilling::VerifyHoleFromBottom( const Hole& hole, SelData Id)
//----------------------------------------------------------------------------
bool
Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId)
Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId, double dMHOff, Vector3d vtA)
{
// aggiusto alcuni parametri del ciclo di foratura
double dStartSlowLen = abs( m_Params.m_dStartSlowLen) ;
@@ -1487,7 +2025,7 @@ Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId)
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ;
double dAppr = ( m_bAggrBottom ? dSafeAggrBottZ : dSafeZ) ;
Point3d ptP1 = hole.ptIni + hole.vtDir * ( dAppr + dElev + dTExtrLen) ;
Point3d ptP1 = hole.ptIni + hole.vtDir * ( dAppr + dElev + dTExtrLen + dMHOff) ;
if ( m_bAggrBottom) {
Point3d ptP0 = ptP1 + m_vtAggrBottom * ( m_dDistBottom + m_AggrBottom.dEncH + dSafeZ) ;
Point3d ptP00 = ptP0 + Z_AX * ( m_AggrBottom.dEncV + m_TParams.m_dLen + dAppr + dTExtrLen) ;
@@ -1514,6 +2052,8 @@ Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId)
return false ;
}
else {
if( ! vtA.IsSmall())
SetAuxDir( vtA) ;
if ( AddRapidStart( ptP1) == GDB_ID_NULL)
return false ;
}
+14 -3
View File
@@ -19,7 +19,13 @@
#include "MachiningConst.h"
struct Hole ;
struct MHDrill ;
struct HoleInfo ;
struct ToolInfo ;
class ICurve ;
typedef std::vector<std::vector<MHDrill>> TABMHDRILL ;
typedef std::vector<HoleInfo> VECTORHOLE ;
typedef std::vector<ToolInfo> VECTORTOOL ;
//----------------------------------------------------------------------------
class Drilling : public Machining
@@ -68,18 +74,23 @@ class Drilling : public Machining
private :
bool GetHoleData( SelData Id, Hole& hole) ;
bool StdandardProcess( bool bRecalc, int nPvId, int nClId) ;
bool StandardProcess( bool bRecalc, int nPvId, int nClId) ;
bool AlongCurveProcess( bool bRecalc, int nPvId, int nClId) ;
bool Chain( int nGrpDestId) ;
ICurve* GetCurve( SelData Id) ;
bool ProcessPath( int nPathId, int nPvId, int nClId) ;
bool GenerateHolePv( int nInd, const SelData& nCircId, const std::string& sPName, int nPvId) ;
bool GenerateHoleCl( int nInd, const SelData& nCircId, const std::string& sPName, int nClId) ;
bool GenerateHoleCl( int nInd, const SelData& nCircId, const std::string& sPName, int nClId, double dMHOff = .0, Vector3d vtAux = V_NULL) ;
bool GenerateHoleRegionPv( int nFirstId, int nCount, int nPvId) ;
bool VerifyDiameter( double dHdiam, double dTdiam, double ddiamTol) ;
bool VerifyHoleFromBottom( const Hole& hole, SelData Id) ;
bool DoStandardDrilling( const Hole& hole, SelData Id, int nPathId) ;
bool DoStandardDrilling( const Hole& hole, SelData Id, int nPathId, double nMHOff, Vector3d vtA) ;
bool DoPeckDrilling( const Hole& hole, SelData Id, int nPathId) ;
bool MultiHeadDrilling( int nExit, const SELVECTOR& vId, int nClId, TABMHDRILL& vDrills, double& dMHOff, bool bOrd = true) ;
bool MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamTol, SelData Id) ;
bool CalcMask( VECTORHOLE& vHoles, VECTORTOOL& vTools, int nIndMT, Vector3d vtT, Vector3d vtA) ;
bool CheckOtherHolesWithTools( VECTORHOLE& vHoles, VECTORTOOL& vTools, int nIndTM, int nIndHTM, Hole holeICP, Frame3d frHTM,
Frame3d frHMTOP, double dDiamTol, int& nDrills) ;
private :
double GetSpeed() const