diff --git a/Drilling.cpp b/Drilling.cpp index 60018da..2aa13fb 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -61,8 +61,13 @@ using namespace std ; // 2157 = "Warning in Drilling : Skipped by Peck Drilling " //---------------------------------------------------------------------------- -struct Hole -{ +// definizione delle costanti +const int IND_TOOL_INVALID = -1 ; +const int IND_HOLE_INVALID = -1 ; + +//---------------------------------------------------------------------------- +// struttura semplificata del foro +struct Hole { int nOriId ; // identificativo della geometria di origine Point3d ptIni ; // punto iniziale Vector3d vtDir ; // direzione di riferimento (dal fondo verso l'inizio) @@ -75,38 +80,45 @@ struct Hole : nOriId( GDB_ID_NULL), ptIni(), vtDir(), dDiam( 0), dThick( 0), dLen( 0), bBlind( true) {} } ; -struct MHDrill { - int nInd_id_hole ; // indice foro - Vector3d vtAux ; // vettore ausiliario per tale foratura +// struttura avanzata per fori nel caso di MultiHeadDrills +struct HoleInfo { + Hole hole ; // foro + bool bDrill = false ; // flag per indicare se il foro alla fine verrà lavorato + bool bTempDrill = false ; // [per test maschera ( se durante un test viene lavorato o no)] + int nTempTool = IND_TOOL_INVALID ; // [per test maschera ( indice utensile che lo lavora durante un test)] + bool bForToolM = false ; // flag per indicare se il tool main lavorerà questo foro + int nIndHoleToolM = IND_HOLE_INVALID ; // se il foro verrà svuotato, contiene l'indice del foro del tool principale + +// --- vettori ordinati --- + INTVECTOR vToolHole ; // []-> indice del foro di inserimento del tool principale + INTVECTOR vIndTools ; // []-> indice del tool che svuoterà il foro corrente + VCT3DVECTOR vVtAux ; // []-> vettore ausiliario per tale condifgurazione + + int nIndTool = IND_TOOL_INVALID ; // indice del tool che alla fine lavorerà il foro + Vector3d vtAux ; // vettore ausiliario del tool principale per lavorare il foro corrente + Point3d ptBtn ; // punto interno alla base del foro + int nIndInSelVector = 0 ; // indice nel vettore m_vId ( id fori selezionati) } ; -struct HoleInfo { - Hole hole ; // foro - bool bDrill = false ; // se alla fine verrà lavorato - bool bTempDrill = false ; // per test maschera (se durante un test viene lavorato o no) - int nTempTool = -1 ; // per test maschera ( indice utensile che lo lavora durante un test) - bool bSkipToAngle = false ; // nel caso di più assi rotanti, se foro già lavorato con testa orientata - bool bForToolM = false ; // se tool main lavorerà 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 lavorazione in vToolHole (ordinati) - VCT3DVECTOR vVtAux ; // vettore dei vtAux ausiliari del tool principale per lavorare questo foro (ordinati) - int nIndTool = -1 ; // indice del tool che alla fine lavorerà il foro - Vector3d vtAux ; // vettore ausiliario del tool principale che permette al tool principale di lavorare questo foro - Point3d ptBtn ; // punto interno alla base del foro - int nIndInSelVector = 0 ; // indice nel vettore m_vId (id fori selezionati) - } ; - -struct ToolInfo -{ - const ToolData* pTool ; // puntatore per utensile (nullo se utensile non presente) - Point3d ptToolTip ; // punto finale del tool (per ptBtn del foro) +// struttura avanzata per il tool, per MultiHeadDrills +struct ToolInfo { + const ToolData* pTool ; // puntatore per utensile ( nullo se utensile non presente) + Point3d ptToolTip ; // punto finale del tool ( per ptBtn del foro) ToolInfo( void) : pTool( nullptr) {} ToolInfo( const ToolData* pT) : pTool( pT) {} } ; +// struttura per foratura con MultiHeadDrills +struct MHDrill { + int nInd_id_hole ; // indice foro + Vector3d vtAux ; // vettore ausiliario per tale foratura + MHDrill( int nIndH, Vector3d vtA) + : nInd_id_hole( nIndH), vtAux( vtA) {} ; +} ; + + //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_DRILLING), Drilling) ; @@ -137,6 +149,7 @@ Drilling::Clone( void) const pDri->m_vtTiltingAx = m_vtTiltingAx ; pDri->m_bAboveHead = m_bAboveHead ; pDri->m_bAggrBottom = m_bAggrBottom ; + pDri->m_vIdUndrilledHoles = m_vIdUndrilledHoles ; } catch( ...) { delete pDri ; @@ -253,8 +266,9 @@ Drilling::Drilling( void) m_nDrillings = 0 ; m_bTiltingTab = false ; m_bAboveHead = true ; - m_bAggrBottom = false ; + m_bAggrBottom = false ; m_dDistBottom = 0 ; + m_vIdUndrilledHoles = {} ; } //---------------------------------------------------------------------------- @@ -776,10 +790,10 @@ Drilling::StandardProcess( bool bRecalc, int nPvId, int nClId) 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][0].nInd_id_hole], MCH_PATH, nPvId)) + 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)) ; @@ -787,7 +801,7 @@ Drilling::StandardProcess( bool bRecalc, int nPvId, int nClId) } // se richiesta lavorazione if ( nClId != GDB_ID_NULL) { - if ( ! GenerateHoleCl( i, m_vId[tabDrills[i][0].nInd_id_hole], MCH_PATH, nClId, dMHOff, tabDrills[i][0].vtAux)) + if ( ! GenerateHoleCl( i, m_vId[tabDrills[i].nInd_id_hole], MCH_PATH, nClId, dMHOff, tabDrills[i].vtAux)) return false ; } } @@ -814,9 +828,385 @@ Drilling::StandardProcess( bool bRecalc, int nPvId, int nClId) return true ; } +//---------------------------------------------------------------------------- +bool +Drilling::CalcDrilledHolesByConfig( VECTORHOLE& vHoles, int nMyInd, int nIndConfig, INTVECTOR& vIndDrilled) +{ + /* + restituisce quali fori non ancora svuotati vengono svuotati con la configurazione di indice nIndConfig + per il foro nMyInd-esimo + */ + + // controllo dei parametri + if ( nMyInd < 0 || nMyInd >= int( vHoles.size()) || + nIndConfig < 0 || nIndConfig >= int( vHoles[nMyInd].vIndTools.size())) + return false ; + vIndDrilled.clear() ; + if ( vHoles.empty()) + return true ; + + // dichiarazione variabili di supporto + int nMainHole = vHoles[nMyInd].vToolHole[nIndConfig] ; + Vector3d vtMainAux = vHoles[nMyInd].vVtAux[nIndConfig] ; + // scorro tutti i fori + for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) { + // se foro i-esimo già lavorato, passo al successivo + if ( vHoles[i].bDrill) + continue ; + // se il foro i-esimo è il corrente, lo inserisco ( è svuotato in quanto nella configurazione) + if ( i == nMyInd) { + vIndDrilled.emplace_back( i) ; + continue ; + } + // se il foro i-esimo è quello in cui il tool è posizionato, lo inserisco ( idem) + else if ( i == nMainHole) { + vIndDrilled.emplace_back( i) ; + continue ; + } + else { + // se foro i-esimo viene svuotato mettendo il tool principale nel foro nMainHole-esimo e con lo + // stesso orientamento della configurazione corrente, inserisco il foro + for ( int j = 0 ; j < int( vHoles[i].vToolHole.size()) ; ++ j) { + if ( vHoles[i].vToolHole[j] == nMainHole && AreSameVectorApprox( vHoles[i].vVtAux[j], vtMainAux)) + vIndDrilled.emplace_back( i) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Drilling::GetClosestHolesToHole( const VECTORHOLE& vHoles, int nMyInd, bool bDrilled, INTVECTOR& vInds) +{ + /* + funzione che restutisce gli indici dei fori Drilled/nonDrilled più vicini al foro nMyInd-esimo + */ + + // controllo dei parametri + if ( nMyInd < 0 || nMyInd >= int( vHoles.size())) + return false ; + vInds.clear() ; + if ( vHoles.empty()) + return true ; + + // scorro i fori + double dMinDist = INFINITO ; + for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) { + // escludo il foro nInd-esimo + if ( i == nMyInd) + continue ; + // se foro di tipologia opposta, passo al successivo + if ( vHoles[i].bDrill != bDrilled) + continue ; + // calcolo la distanza tra i due fori + double dSqDist = SqDist( vHoles[nMyInd].hole.ptIni, vHoles[i].hole.ptIni) ; + if ( dSqDist < dMinDist) { + dMinDist = dSqDist ; + vInds.clear() ; + vInds.emplace_back( i) ; + } + else if ( abs( dSqDist - dMinDist) < 100 * SQ_EPS_SMALL) + vInds.emplace_back( i) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Drilling::EraseDuplicatedConfigs( VECTORHOLE& vHoles) +{ + /* funzione per rimuovere le configurazioni tra loro equivalenti */ + + // scorro il vettore dei fori + if ( vHoles.empty()) + return true ; + + // analizzo il primo foro selezionato e scorro le configurazioni + for ( int nC = 0 ; nC < int( vHoles[0].vIndTools.size()) - 1 ; ++ nC) { + for ( int nC1 = nC + 1 ; nC1 < int( vHoles[0].vToolHole.size()) ; ++ nC1) { + if ( vHoles[0].vToolHole[nC] == vHoles[0].vToolHole[nC1] && + vHoles[0].vIndTools[nC] == vHoles[0].vIndTools[nC1] && + ( AreSameVectorApprox( vHoles[0].vVtAux[nC], vHoles[0].vVtAux[nC1]) || + ( ! vHoles[0].vVtAux[nC].IsValid() && ! vHoles[0].vVtAux[nC1].IsValid()))) { + // controllo se vale anche per gli altri fori + bool bSame = true ; + for ( int i = 1 ; i < int( vHoles.size()) && bSame ; ++ i) { + bSame = ( vHoles[i].vToolHole[nC] == vHoles[i].vToolHole[nC1] && + vHoles[i].vIndTools[nC] == vHoles[i].vIndTools[nC1] && + ( AreSameVectorApprox( vHoles[i].vVtAux[nC], vHoles[i].vVtAux[nC1]) || + ( ! vHoles[i].vVtAux[nC].IsValid() && ! vHoles[i].vVtAux[nC1].IsValid()))) ; + } + if ( bSame) { + for ( int k = 0 ; k < int( vHoles.size()) ; ++ k) { + vHoles[k].vToolHole.erase( vHoles[k].vToolHole.begin() + nC1) ; + vHoles[k].vIndTools.erase( vHoles[k].vIndTools.begin() + nC1) ; + vHoles[k].vVtAux.erase( vHoles[k].vVtAux.begin() + nC1) ; + } + -- nC1 ; + } + } + } + } + + return true ; + +} + +//---------------------------------------------------------------------------- +bool +Drilling::KeepMinRotatedConfigs( VECTORHOLE& vHoles, const Vector3d vtAux, const Vector3d vtTool) +{ + /* riduco il numero di cobinazioni in base a vtAux */ + + // se non ho fori, allora esco + if ( vHoles.empty()) + return true ; + + // scorro il vettore dei fori + for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) { + Vector3d vtMinAndDegAux ; + double dMinAngDeg = ANG_FULL ; + for ( int j = 0 ; j < int( vHoles[i].vVtAux.size()) ; ++ j) { + // se non valido, passo al successivo + if ( ! vHoles[i].vVtAux[j].IsValid()) + continue ; + // calcolo l'angolo con segno della configurazione rispetto a vtAux + double dAngDeg ; + bool bDet ; + if ( ! vHoles[i].vVtAux[j].GetRotation( vtAux, vtTool, dAngDeg, bDet)) + return false ; + // conservo l'angolo minimo + if ( abs( dAngDeg) < dMinAngDeg) { + dMinAngDeg = abs( dAngDeg) ; + vtMinAndDegAux = vHoles[i].vVtAux[j] ; + } + } + for ( int j = 0 ; j < int( vHoles[i].vVtAux.size()) ; ++ j) { + // se vettore ausiliario corrente diverso da quello minimo e non presente tra le configurazioni + // valide, allora rendo invalida la configurazione + if ( vHoles[i].vVtAux[j].IsValid() && ! AreSameOrOppositeVectorApprox( vHoles[i].vVtAux[j], vtMinAndDegAux)) { + vHoles[i].vToolHole[j] = IND_TOOL_INVALID ; + vHoles[i].vIndTools[j] = IND_TOOL_INVALID ; + vHoles[i].vVtAux[j] = V_INVALID ; + } + } + } + + // cancello tutte le configurazioni invalide + int nSize = int( vHoles[0].vIndTools.size()) ; + for ( int j = 0 ; j < nSize ; ++ j) { + bool bInvalid = true ; + for ( int i = 0 ; i < int( vHoles.size()) && bInvalid ; ++ i) + bInvalid = ( vHoles[i].vIndTools[j] == IND_TOOL_INVALID && + vHoles[i].vToolHole[j] == IND_TOOL_INVALID && + ! vHoles[i].vVtAux[j].IsValid()) ; + if ( bInvalid) { + for ( int k = 0 ; k < int( vHoles.size()) ; ++ k) { + vHoles[k].vToolHole.erase( vHoles[k].vToolHole.begin() + j) ; + vHoles[k].vIndTools.erase( vHoles[k].vIndTools.begin() + j) ; + vHoles[k].vVtAux.erase( vHoles[k].vVtAux.begin() + j) ; + } ; + -- nSize ; + -- j ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Drilling::CalcMultyHeadUndrilledHoles( const VECTORHOLE& vHoles, INTVECTOR& vIdUndrilledHoles) +{ + /* funzione per calcolare gli Id dei fori fori non svuotati */ + + // se non ho fori, ho finito + vIdUndrilledHoles.clear() ; + if ( vHoles.empty()) + return true ; + + // scorro sui fori + 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 svuotabile, lo inserisco nel vettore + if ( bIsUndrilled) + vIdUndrilledHoles.emplace_back( vHoles[i].hole.nOriId) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Drilling::CheckBasedConfig( const VECTORHOLE& vHoles, int nIndHole, int& nValidConfig, bool& bBaseCase) +{ + // controllo dei parametri + if ( nIndHole < 0 || nIndHole >= int( vHoles.size())) + return false ; + if ( vHoles.empty()) + return false ; + + bBaseCase = false ; + nValidConfig = 0 ; + Vector3d vtAuxRef ; + for ( int i = 0 ; i < int( vHoles[nIndHole].vIndTools.size()) ; ++ i) { + if ( vHoles[nIndHole].vIndTools[i] != IND_TOOL_INVALID) { + ++ nValidConfig ; + if ( nValidConfig == 1) + vtAuxRef = vHoles[nIndHole].vVtAux[i] ; + else { + // controllo se i versori ausiliari sono opposti + if ( ! AreOppositeVectorApprox( vtAuxRef, vHoles[nIndHole].vVtAux[i])) + return true ; + } + } + } + bBaseCase = ( nValidConfig == 1 || nValidConfig == 2) ; + return true ; +} + + +//---------------------------------------------------------------------------- +bool +Drilling::MultiHeadOrderConfig( TABMHDRILL& tabDrills, const VECTORHOLE& vHoles, + const Vector3d& vtTool, const Vector3d& vtAux) +{ + /* funzione per riordinare le calate; viene creato un frame mediante vtTool e vtAux e si ordinano + i punti in locale a tale frame in base alla vicinanza che hanno dal punto minimo del boxXY */ + + // se non ho calate, non faccio nulla + if ( tabDrills.empty()) + return true ; + + // creo il sistema di riferimento locale + Frame3d frOrder ; + if ( ! frOrder.Set( ORIG, vtTool, vtAux)) + return false ; + // creo un vettore con i punti sulla base superiore dei fori in locale a tale frame + // li inserisco anche nel Box + PNTVECTOR vPtLoc ; + BBox3d BBoxOrder ; + for ( int i = 0 ; i < int( tabDrills.size()) ; ++ i) { + vPtLoc.emplace_back( GetToLoc( vHoles[tabDrills[i].nInd_id_hole].hole.ptIni, frOrder)) ; + BBoxOrder.Add( vPtLoc.back()) ; + } + // recupero il punto minimo del Box + Point3d ptMinBoxOrder = BBoxOrder.GetMin() ; + // cerco l'indice della tabDrills il cui foro è più vicino al punto di minimo del box trovato + int nIndClosestHole = 0 ; + double dSqMinDist = INFINITO ; + for ( int i = 0 ; i < int( vPtLoc.size()) ; ++ i) { + double dCurrSqDist = SqDist( vPtLoc[i], ptMinBoxOrder) ; + if ( dCurrSqDist < dSqMinDist) { + dSqMinDist = dCurrSqDist ; + nIndClosestHole = i ; + } + } + // metto l'indice trovato in prima posizione + swap( tabDrills[nIndClosestHole], tabDrills[0]) ; + + // una volta determinato il primo foro + struct OrderTabDrill { + int nInd_id_hole ; + Point3d ptIni ; + OrderTabDrill( int nInH, Point3d ptI) + : nInd_id_hole( nInH), ptIni( ptI) {} ; + } ; + vector vOrderedTab ; + for ( int i = 0 ; i < int( tabDrills.size()) ; ++ i) + vOrderedTab.emplace_back( tabDrills[i].nInd_id_hole, vHoles[tabDrills[i].nInd_id_hole].hole.ptIni) ; + // per sicurezza ... + if ( vOrderedTab.empty()) + return false ; + + // prendo come riferimento il primo punto + Point3d ptRef = vOrderedTab[0].ptIni ; + double dMinSqDist = INFINITO ; + int nIndexSwitch = -1 ; + // ordino le successioni di calate + for ( int i = 0 ; i < int( vOrderedTab.size()) - 1 ; ++ i) { + for ( int j = i + 1 ; j < int( vOrderedTab.size()) ; ++ j) { + Point3d ptS = vOrderedTab[j].ptIni ; + double dSqCurrDist = SqDist( ptS, ptRef) ; + if ( dSqCurrDist < dMinSqDist) { + dMinSqDist = dSqCurrDist ; + nIndexSwitch = j ; + } + } + if ( nIndexSwitch != i + 1) { + swap( vOrderedTab[nIndexSwitch], vOrderedTab[i + 1]) ; + swap( tabDrills[nIndexSwitch], tabDrills[i + 1]) ; + } + + ptRef = vOrderedTab[i + 1].ptIni ; + dMinSqDist = INFINITO ; + } + + return true ; + +} + +//---------------------------------------------------------------------------- +bool +Drilling::GetHoleBestConfig( VECTORHOLE& vHoles, int nInd, TABMHDRILL& tabDrills, const Vector3d& vtAux, + const Vector3d& vtTool, int& nOkHole) +{ + // salvo gli indici dei fori ( non ancora svuotati) che vengono svuotati con la sola consifugrazione presente + int nMaxDrilledHoles = - 1 ; + INTVECTOR vInds ; + int nRefConfig = -1 ; + // scorro le configurazioni presenti + for ( int i = 0 ; i < int( vHoles[nInd].vToolHole.size()) ; ++ i) { + // se configurazione non valida passo alla successiva + if ( vHoles[nInd].vToolHole[i] == IND_TOOL_INVALID || /*&&*/ + vHoles[nInd].vIndTools[i] == IND_TOOL_INVALID || /*&&*/ + ! vHoles[nInd].vVtAux[i].IsValid()) + continue ; + // determino se esiste la prima configurazione ammissibile per tale foro + INTVECTOR vIndsTemp ; + if ( ! CalcDrilledHolesByConfig( vHoles, nInd, i, vIndsTemp)) + return false ; + if ( int( vIndsTemp.size()) > nMaxDrilledHoles) { + nMaxDrilledHoles = int( vIndsTemp.size()) ; + nRefConfig = i ; + vInds = vIndsTemp ; + } + else if ( int( vIndsTemp.size()) == nMaxDrilledHoles) { + double dAngDeg0, dAngDeg1 ; + bool bDet0, bDet1 ; + if ( ! vHoles[nInd].vVtAux[nRefConfig].GetRotation( vtAux, vtTool, dAngDeg0, bDet0) || + ! vHoles[nInd].vVtAux[i].GetRotation( vtAux, vtTool, dAngDeg1, bDet1)) + return false ; + if ( abs( dAngDeg0) > abs( dAngDeg1) + EPS_ANG_SMALL) { + nRefConfig = i ; + vInds = vIndsTemp ; + } + } + } + // assegno flag per fori svuotati + for ( int i = 0 ; i < int( vInds.size()) ; ++ i) + vHoles[vInds[i]].bDrill = true ; + // assegno posizioni di ToolMain + if ( nRefConfig != -1) { + tabDrills.emplace_back( vHoles[nInd].vToolHole[nRefConfig], vHoles[nInd].vVtAux[nRefConfig]) ; + nOkHole += int( vInds.size()) ; + } + + return true ; +} + + //---------------------------------------------------------------------------- bool -Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDrills, double& dMHOff, bool bOrd) +Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDrills, double& dMHOff) { // controllo parametri tabDrills.clear() ; @@ -894,10 +1284,10 @@ Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDri // Recupero le geometrie dei fori bool bSomeHoleOk = false ; VECTORHOLE vHoles( vId.size()) ; - for ( int h = 0 ; h < ( int)vId.size() ; ++ h) { + for ( int nH = 0 ; nH < int( vId.size()) ; ++ nH) { Hole hole ; - if ( ! GetHoleData( m_vId[h], hole)) { - string sInfo = "Warning in Drilling : Skipped entity " + ToString( m_vId[h]) ; + if ( ! GetHoleData( m_vId[nH], hole)) { + string sInfo = "Warning in Drilling : Skipped entity " + ToString( m_vId[nH]) ; m_pMchMgr->SetWarning( 2151, sInfo) ; continue ; } @@ -916,8 +1306,8 @@ Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDri if ( hole.dLen < hole.dThick - 10 * EPS_SMALL) hole.bBlind = true ; - vHoles[h].hole = hole ; - vHoles[h].nIndInSelVector = h ; + vHoles[nH].hole = hole ; + vHoles[nH].nIndInSelVector = nH ; bSomeHoleOk = true ; } if ( ! bSomeHoleOk) @@ -928,150 +1318,111 @@ Drilling::MultiHeadDrilling( const SELVECTOR& vId, int nClId, TABMHDRILL& tabDri // applico eventuali blocchi di assi rotanti m_pMchMgr->ApplyRotAxisBlock() ; - // calcolo la corrispondenza tra utensili e fori + // calcolo la maschera di corrispondenza tra utensili e fori if ( ! CalcMask( vHoles, vTools, nMainToolInd, vtTool, vtAux)) return false ; - // i fori con dimensione 0 del vettore vToolHole non possono essere lavorati - int nNoDrillHoles = 0 ; - for ( int i = 0 ; i < ( int)vHoles.size() ; ++ i) { - if ( vHoles[i].vToolHole.empty()) - ++ nNoDrillHoles ; - } + // riduco il numeor di configurazioni in base a vtAux + if ( ! KeepMinRotatedConfigs( vHoles, vtAux, vtTool)) + return false ; - // resetto le variabili di controllo di lavorazione temporanea per tutti i fori - for ( int k = 0 ; k < ( int)vHoles.size() ; ++k) - vHoles[k].bTempDrill = false ; + // calcolo i fori non svuotati + if ( ! CalcMultyHeadUndrilledHoles( vHoles, m_vIdUndrilledHoles)) + return false ; + // per ogni foro non svuotato, segnalo il Warning + int nNoDrillHoles = int( m_vIdUndrilledHoles.size()) ; + if ( ! m_vIdUndrilledHoles.empty()) { + string sIndHoles = "" ; + for ( int i = 0 ; i < nNoDrillHoles ; ++ i) + sIndHoles.append( ToString( m_vIdUndrilledHoles[i]) + ( i != nNoDrillHoles - 1 ? ", " : "")) ; + string sInfo = "Warning in Drilling : Skipped entities " + sIndHoles ; + m_pMchMgr->SetWarning( 2151, sInfo) ; + } + // se non posso svuotare nessun foro, esco + if ( nNoDrillHoles == int( vHoles.size())) + return true ; // numero di fori lavorati int nOkHole = 0 ; - // se c'è un solo foro va sicuramente bene - if ( vHoles.size() == 1 && ! vHoles[0].vVtAux.empty()) { + if ( int( vHoles.size()) == 1 && ! vHoles[0].vVtAux.empty()) { vHoles[0].bForToolM = true ; vHoles[0].nIndTool = nMainToolInd ; vHoles[0].nIndHoleToolM = 0 ; vHoles[0].vtAux = vHoles[0].vVtAux[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) { - // prendo tutti i fori con vToolHope di lunghezza nCheck non già lavorati - if ( vHoles[i].vToolHole.size() == nCheck && ! vHoles[i].bDrill) { - vHoles[vHoles[i].vToolHole[0]].bForToolM = true ; - vHoles[vHoles[i].vToolHole[0]].nIndTool = nMainToolInd ; - 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[nMainToolInd].pTool->m_dTLen ; double dOffMax = 0 ; - for ( int nT = 0 ; nT < ( int)vTools.size() && nNoDrillHoles != (int)vHoles.size() ; ++ nT) { + for ( int nT = 0 ; nT < int( vTools.size()) && nNoDrillHoles != int( vHoles.size()) ; ++ nT) { if ( vTools[nT].pTool == nullptr || nT == nMainToolInd) continue ; - if ( vTools[nT].pTool->m_dTLen > dRefLen + dOffMax) { + if ( vTools[nT].pTool->m_dTLen > dRefLen + dOffMax) dOffMax = vTools[nT].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) + /* Inizio a considerare i fori che presentano meno configurazioni per essere svuotati. + Esso sono i più critici, quindi vengono gestiti per primi, scremando quindi le configurazioni + degli altri fori. + Parto ad analizzare i fori svuotabili 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 ; - // 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 ( vVtA.empty()) - 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() ; + // 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 svuotati) che vengono svuotati con la sola configurazione presente + if ( ! GetHoleBestConfig( vHoles, i, tabDrills, vtAux, vtTool, nOkHole)) + return false ; } - // se non trovo corrispondenze ... + // se nessun foro svuotabile, esco ( fino a prova contraria non esco mai...) if ( tabDrills.empty()) - return true ; + return false ; - // se devo riordinare - if ( bOrd) { - struct Order { - int nInd_id_hole ; - Point3d ptIni ; - } ; - vector 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) ; - } + /* Una volta scremate le configurazioni critiche, cerco i fori non svuotati più vicini ad essi. + L'idea è che avendo svuotato i fori a signola configurazione, ottengo meno combinazioni + per i fori ad esso adiacenti... l'idea si ripete per tutti i fori successivi */ - // 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 ; - } + // per vicinanza cerco gli altri fori oltre ai casi base + while ( nOkHole < int( vHoles.size()) - nNoDrillHoles) { + 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 svuotati 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, 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 + */ + // controllo dei parametri if ( vHoles.empty() || vTools.empty()) return false ; @@ -1079,34 +1430,31 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co // recupero il valore di tolleranza sul diametro double dDiamToler = GetHoleDiamToler() ; - int nExitCnt = ( int)vTools.size() ; + int nExitCnt = int( vTools.size()) ; int nNullTools = 0 ; - for ( int i = 0 ; i < ( int)vTools.size() ; ++ i) { + 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) { - + for ( int i = 0 ; i < int( vHoles.size()) ; ++ i) { // 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 ; - vHoles[k].nTempTool = -1 ; + for ( int j = 0 ; j < int( vHoles.size()) ; ++ j) { + vHoles[j].bTempDrill = false ; + vHoles[j].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, dDiamToler, m_vId[vHoles[i].nIndInSelVector])) continue ; - int nStat ; DBLVECTOR vAng1, vAng2 ; - // angoli per allineare T del tool principale con vtDir del foro i-esimo + // 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 ; - // check che T sia allineato con vtDir + // check che versore T sia allineato con vtDir if ( ! m_pMchMgr->GetCalcToolDirFromAngles( vAng1, vtTnew) || ! AreSameVectorApprox( vtTnew, Hole_i.vtDir)) continue ; Vector3d vtAnew ; @@ -1121,13 +1469,11 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co frMT.Set( vTools[nIndMT].ptToolTip, vtTool, vtAux) ; 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 ; + Frame3d frHMT ; frHMT.Set( Hole_i.ptIni - Hole_i.vtDir * Hole_i.dLen, vtTnew, vtAnew) ; if ( ! frHMT.IsValid()) return false ; - // numero di forature inserendo il Tool principale nel foro i-esimo int nDrills = 1 ; // setto le variabili temporanee per il foro i-esimo @@ -1136,48 +1482,49 @@ 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 svuotare e setto i loro parametri di foratura if ( nDrills == nExitCnt - 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 + 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 svuota 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 d = 0 ; d < ( int)vHoles.size() ; ++ d) - if ( vHoles[d].bTempDrill) - vHoles[d].bTempDrill = false ; + else { + for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD) + vHoles[nD].bTempDrill = false ; } // se la testa può ruotare if ( nStat < 0) { - // inizio a scorrere tutti i tools - for ( int t = 0 ; t < ( int)vTools.size() ; ++ t) { - if ( vTools[t].pTool == nullptr || t == nIndMT) + for ( int nT = 0 ; nT < int( vTools.size()) ; ++ nT) { + if ( vTools[nT].pTool == nullptr || nT == nIndMT) continue ; - // cerco se ho un foro j-esimo adatto per quella punta - for ( int j = 0 ; j < ( int)vHoles.size() ; ++ j) { - + 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, dDiamToler, m_vId[vHoles[j].nIndInSelVector])) + ! MultiHeadVerifyHole( Hole_j, vTools[nT].pTool, dDiamToler, m_vId[vHoles[j].nIndInSelVector])) continue ; - // resetto le variabili di controllo di foratura temporanea per tutti i fori - for ( int k = 0 ; k < ( int)vHoles.size() ; ++ k) { + for ( int k = 0 ; k < int( vHoles.size()) ; ++ k) { vHoles[k].bTempDrill = false ; - vHoles[k].nTempTool = -1 ; + vHoles[k].nTempTool = IND_TOOL_INVALID ; } - Vector3d vtRefT = vTools[t].ptToolTip - vTools[nIndMT].ptToolTip ; + // calcolo il vettore uscente dal tool Main e diretto al tool nT-esimo + Vector3d vtRefT = vTools[nT].ptToolTip - vTools[nIndMT].ptToolTip ; + // calcolo il vettore uscente dal foro i-esimo e diretto al foro j-esimo Vector3d vtRefH = Hole_j.ptIni - Hole_j.vtDir * Hole_j.dLen - ( Hole_i.ptIni - Hole_i.vtDir * Hole_i.dLen) ; @@ -1187,12 +1534,12 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co 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].ptToolTip ; + + Point3d ptTt = vTools[nT].ptToolTip ; ptTt.ToLoc( frMT) ; Vector3d vtProjA( ptTt.x, ptTt.y, 0) ; - - double dAngle ; vtProjA.GetAngle( vtProjB, dAngle) ; + + double dAngle ; vtProjA.GetAngleXY( vtProjB, dAngle) ; frHMT.Rotate( frHMT.Orig(), frHMT.VersZ(), dAngle) ; nDrills = 1 ; // foratura nel foro i-esimo e j-esimo @@ -1204,28 +1551,33 @@ Drilling::CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, co // controllo quanti fori sono riuscito a lavorare in questo nuovo sistema di riferimento if ( nDrills == nExitCnt - 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 lavora questo foro - vHoles[d].vVtAux.push_back( frHMT.VersX()) ; // versore ausiliario del tool principale - vHoles[d].bSkipToAngle = true ; + 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 d = 0 ; d < ( int)vHoles.size() ; ++ d) - if ( vHoles[d].bTempDrill) - vHoles[d].bTempDrill = false ; + for ( int nD = 0 ; nD < int( vHoles.size()) ; ++ nD) + vHoles[nD].bTempDrill = false ; } - } } - } } } + // cancello le configurazioni identiche tra loro ( possono capitare quando i tools sono già + // allineati con i fori) + EraseDuplicatedConfigs( vHoles) ; return true ; } @@ -1234,48 +1586,51 @@ bool Drilling::CheckOtherHolesWithTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndTM, int nIndHTM, Hole holeICP, const Frame3d& frMT, const Frame3d& frHMT, double dDiamToler, int& nDrills) { + /* + supponendo di inserire il tool principale nel foro nIndTM-esimo vengono controllate + le compatibilità tra gli altri utensili e gli altri fori + */ + // controllo parametri if ( vHoles.empty() || vTools.empty()) return true ; - if ( nIndTM < 0 || nIndTM >= ( int)vTools.size() || - nIndHTM < 0 || nIndHTM >= ( int)vHoles.size() || + if ( nIndTM < 0 || nIndTM >= int( vTools.size()) || + nIndHTM < 0 || nIndHTM >= int( vHoles.size()) || ! frMT.IsValid() || ! frHMT.IsValid() || - nDrills < 0 || nDrills > max( ( int)vHoles.size(), ( int)vTools.size())) + 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) + for ( int nT = 0 ; nT < int( vTools.size()) ; ++ nT) { + if ( vTools[nT].pTool == nullptr || nT == nIndTM) continue ; // esprimo il punto finale del tool t-esimo nel sistema di riferimento del Tool principale - Point3d ptETt = vTools[t].ptToolTip ; + Point3d ptETt = vTools[nT].ptToolTip ; ptETt.ToLoc( frMT) ; - // cerco se ho un foro j-esimo adatto per quella punta - for ( int j = 0 ; j < ( int)vHoles.size() ; ++ j) { + 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 lavorato 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 + // controllo che il foro j-esimo non sia l'i-esimo, che non sia stato già precedentemente lavorato + // da un altro tool t'-esimo e 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, dDiamToler, m_vId[vHoles[j].nIndInSelVector])) + ! MultiHeadVerifyHole( Hole_j, vTools[nT].pTool, dDiamToler, 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)) { - // un foro in più lavorato - ++ nDrills ; + // aggiorno il numero di fori lavorati + ++ nDrills ; // aggiorno le variabili temporanee vHoles[j].bTempDrill = true ; - vHoles[j].nTempTool = t ; + vHoles[j].nTempTool = nT ; // non controllo gli altri vertici per la punta t-esima break ; } @@ -1289,6 +1644,11 @@ Drilling::CheckOtherHolesWithTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools bool Drilling::MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamToler, SelData Id) { + /* + funzione per verificare la compatibilità tra un utensile e un foro, vengono controllati + i diametri, le profondità e i percorsi dal basso + */ + // verifico che il diamtro del tool sia compatibile con quello del foro if ( ! VerifyDiameter( hole.dDiam, Tool->m_dDiam, dDiamToler)) return false ; @@ -1301,7 +1661,7 @@ Drilling::MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamTol hole.dLen = dElev ; } // limito lunghezza foro a massima lavorazione della punta - double dAddLen = ( hole.bBlind ? 0 : m_Params.m_dThroughAddLen) ; + 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 ; diff --git a/Drilling.h b/Drilling.h index baf1200..eb50455 100644 --- a/Drilling.h +++ b/Drilling.h @@ -23,7 +23,7 @@ struct MHDrill ; struct HoleInfo ; struct ToolInfo ; class ICurve ; -typedef std::vector> TABMHDRILL ; +typedef std::vector TABMHDRILL ; typedef std::vector VECTORHOLE ; typedef std::vector VECTORTOOL ; @@ -86,11 +86,19 @@ 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 bOrd = true) ; + 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 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 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) ; private : @@ -106,16 +114,17 @@ class Drilling : public Machining { return ( IsNullLenValue( m_Params.m_dTipFeed) ? m_TParams.m_dTipFeed : m_Params.m_dTipFeed) ; } private : - SELVECTOR m_vId ; // identificativi entità geometriche da lavorare - DrillingData m_Params ; // parametri lavorazione - ToolData m_TParams ; // parametri utensile - int m_nStatus ; // stato di aggiornamento della lavorazione - int m_nDrillings ; // numero di fori generati - bool m_bTiltingTab ; // flag utilizzo tavola basculante - Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante - bool m_bAboveHead ; // flag utilizzo testa da sopra - bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto - Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto - double m_dDistBottom ; // distanza del foro dal bordo del grezzo - AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto + SELVECTOR m_vId ; // identificativi entità geometriche da lavorare + DrillingData m_Params ; // parametri lavorazione + ToolData m_TParams ; // parametri utensile + int m_nStatus ; // stato di aggiornamento della lavorazione + int m_nDrillings ; // numero di fori generati + bool m_bTiltingTab ; // flag utilizzo tavola basculante + Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante + bool m_bAboveHead ; // flag utilizzo testa da sopra + bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto + Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto + double m_dDistBottom ; // distanza del foro dal bordo del grezzo + AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto + INTVECTOR m_vIdUndrilledHoles ; // vettore degli indici dei fori non svuotati } ;