From 0e8c41192ddc261e2aa4eef4bab5f58c19a9321d Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Thu, 16 Feb 2023 15:11:47 +0100 Subject: [PATCH] =?UTF-8?q?EgtMachKernel=20:=20-=20Fori=20con=20pi=C3=B9?= =?UTF-8?q?=20tools.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Drilling.cpp | 578 +++++++++++++++++++++++++++++++++++++++++++++++++-- Drilling.h | 17 +- 2 files changed, 573 insertions(+), 22 deletions(-) diff --git a/Drilling.cpp b/Drilling.cpp index efe5bdc..6cfba16 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -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 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 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 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 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 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 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 ; } diff --git a/Drilling.h b/Drilling.h index 299e8aa..c66c998 100644 --- a/Drilling.h +++ b/Drilling.h @@ -19,7 +19,13 @@ #include "MachiningConst.h" struct Hole ; +struct MHDrill ; +struct HoleInfo ; +struct ToolInfo ; class ICurve ; +typedef std::vector> TABMHDRILL ; +typedef std::vector VECTORHOLE ; +typedef std::vector 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