diff --git a/Drilling.cpp b/Drilling.cpp index c8f85fc..90cbce0 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -1,13 +1,14 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2015 +// EgalTech 2015-2023 //---------------------------------------------------------------------------- -// File : Drilling.cpp Data : 21.05.15 Versione : 1.6e7 +// File : Drilling.cpp Data : 20.12.23 Versione : 2.5l47 // Contenuto : Implementazione gestione forature. // // Note : Questa lavorazione è sempre espressa nel riferimento globale. // // Modifiche : 21.05.15 DS Creazione modulo. -// +// 20.12.23 RE Forature multiple con aggregati. +// // //---------------------------------------------------------------------------- @@ -19,6 +20,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 +29,7 @@ #include "/EgtDev/Include/EGkUserObjFactory.h" #include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EgtPointerOwner.h" +#include "/EgtDev/Include/EGkGeoFrame3d.h" using namespace std ; @@ -46,6 +49,8 @@ using namespace std ; // 2113 = "Error in Drilling : post apply not calculable" // 2114 = "Error in Drilling : blind hole not reversible" // 2115 = "Error in Drilling : Mirror for Double calculation failed" +// 2116 = "Error in Drilling : multi drilling head without valid tools" +// 2117 = "Error in Drilling : incorrect multi drilling head" // 2151 = "Warning in Drilling : Skipped entity (xx)" // 2152 = "Warning in Drilling : No machinable path" // 2153 = "Warning in Drilling : Tool name changed (xx)" @@ -69,6 +74,39 @@ 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 +} ; + +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) + ToolInfo( void) + : pTool( nullptr) {} + ToolInfo( const ToolData* pT) + : pTool( pT) {} +} ; + //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_DRILLING), Drilling) ; @@ -452,16 +490,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]) ; } @@ -515,7 +553,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) ; @@ -580,7 +618,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 @@ -676,10 +714,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 nExitCnt = m_pMchMgr->GetCurrMachine()->GetHeadExitCount( sCurrHead) ; + TABMHDRILL tabDrills ; + double dMHOff = 0 ; + // se ho più uscite... + if ( nExitCnt > 1) { + if ( ! MultiHeadDrilling( nExitCnt, 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 @@ -696,12 +766,491 @@ Drilling::StdandardProcess( bool bRecalc, int nPvId, int nClId) return false ; } // incremento indice - ++ i ; + ++i ; } return true ; } +//---------------------------------------------------------------------------- +bool +Drilling::MultiHeadDrilling( int nExitCnt, const SELVECTOR& vId, int nClId, TABMHDRILL& tabDrills, double& dMHOff, bool bOrd) +{ + // controllo parametri + tabDrills.clear() ; + if ( vId.empty()) + return true ; + + // recupero il nome della testa + string sHead ; + m_pMchMgr->GetCurrMachine()->GetCurrHead( sHead) ; + + // gestore degli utensili + ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; + if ( pTMgr == nullptr) + return false ; + + // Recupero i dati degli utensili montati sulla testa + int nMainToolInd = -1 ; + VECTORTOOL vTools ; vTools.reserve( nExitCnt) ; + // ricavo gli utensili presenti sulle uscite + for ( int nT = 0 ; nT < nExitCnt ; ++ nT) { + string sToolName ; + ToolInfo TInf ; + if ( ! m_pMchMgr->GetLoadedTool( sHead, nT + 1, sToolName) || sToolName.empty()) { + // non c'è utensile + vTools.emplace_back( nullptr) ; + continue ; + } + // se presente e valido + const ToolData* pTdata = pTMgr->GetTool( sToolName) ; + vTools.emplace_back( pTdata) ; + + // imposto il tool di riferimento come il tool m_TParams + if ( pTdata->m_Uuid == m_TParams.m_Uuid) + nMainToolInd = nT ; + } + // se non ho utensili attivi o validi, errore + if ( nMainToolInd == -1 || vTools.empty()) { + m_pMchMgr->SetLastError( 2116, "Error in Drilling : multi drilling head without valid tools") ; + return false ; + } + + // carico i dati della testa con le sue uscite + Vector3d vtTool, vtAux ; + for ( int nT = 0 ; nT < nExitCnt ; ++ nT) { + // se non attrezzato, salto al successivo + if ( vTools[nT].pTool == nullptr) + continue ; + // recupero i dati dell'uscita + Point3d ptExit ; + Vector3d vtCurrDir, vtCurrAux ; + m_pMchMgr->GetCurrMachine()->GetHeadExitPosDirAux( sHead, nT + 1, ptExit, vtCurrDir, vtCurrAux) ; + // se utensile successivo + if ( ! vtTool.IsSmall()) { + // controllo abbia la stessa direzione dei precedenti, altrimenti errore + if ( ! AreSameVectorApprox( vtCurrDir, vtTool)) { + vtTool = V_NULL ; + break ; + } + } + // altrimenti primo utensile + else { + vtTool = vtCurrDir ; + vtAux = vtCurrAux ; + } + // assegno tip utensile + vTools[nT].ptToolTip = ptExit - vtCurrDir * vTools[nT].pTool->m_dLen ; + } + if ( vtTool.IsSmall() || vtAux.IsSmall()) { + m_pMchMgr->SetLastError( 2117, "Error in Drilling : incorrect multi drilling head") ; + return false ; + } + + // Recupero le geometrie dei fori + bool bSomeHoleOk = false ; + VECTORHOLE vHoles( vId.size()) ; + 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 ; + bSomeHoleOk = true ; + } + if ( ! bSomeHoleOk) + return true ; + + // calcolo la 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.size() == 0) + ++ nNoDrillHoles ; + } + + // 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 ; + + // numero di fori lavorati + 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 = 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) { + if ( vTools[nT].pTool == nullptr || nT == nMainToolInd) + continue ; + 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) + 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 non trovo corrispondenze ... + if ( tabDrills.empty()) + return true ; + + // 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) ; + } + + // 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, const VECTORTOOL& vTools, int nIndMT, const Vector3d& vtTool, const Vector3d& vtAux) +{ + // controllo dei parametri + if ( vHoles.empty() || vTools.empty()) + return false ; + + // recupero il valore di tolleranza sul diametro + double dDiamToler = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ; + + int nExitCnt = ( 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, 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 + 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].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 ; + 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, 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 + } + } + } + else { + for ( int d = 0 ; d < ( int)vHoles.size() ; ++ d) + if ( vHoles[d].bTempDrill) + vHoles[d].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) + 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, dDiamToler, 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].ptToolTip - vTools[nIndMT].ptToolTip ; + Vector3d vtRefH = Hole_j.ptIni - Hole_j.vtDir * Hole_j.dLen - + ( Hole_i.ptIni - Hole_i.vtDir * Hole_i.dLen) ; + + // se le distanze sono compatibili + if ( abs( vtRefH.Len() - vtRefT.Len()) < EPS_SMALL) { + // 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].ptToolTip ; + 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, dDiamToler, 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 == 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 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, const VECTORTOOL& vTools, int nIndTM, int nIndHTM, Hole holeICP, + const Frame3d& frMT, const Frame3d& frHMT, double dDiamToler, int& nDrills) +{ + // controllo parametri + if ( vHoles.empty() || vTools.empty()) + return true ; + 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())) + 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].ptToolTip ; + 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, 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 le variabili temporanee + vHoles[j].bTempDrill = true ; + vHoles[j].nTempTool = t ; + // non controllo gli altri vertici per la punta t-esima + break ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Drilling::MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamToler, SelData Id) +{ + // verifico che il diamtro del tool sia compatibile con quello del foro + if ( ! VerifyDiameter( hole.dDiam, Tool->m_dDiam, dDiamToler)) + 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) @@ -994,12 +1543,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 @@ -1009,7 +1558,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()) ; @@ -1077,7 +1626,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 ; } @@ -1495,7 +2044,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) ; @@ -1525,7 +2074,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) ; @@ -1552,6 +2101,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 41287b0..8296d5e 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 nExitCnt, const SELVECTOR& vId, int nClId, TABMHDRILL& vDrills, double& dMHOff, bool bOrd = true) ; + bool CalcMask( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndMT, const Vector3d& vtTool, const Vector3d& vtAux) ; + bool CheckOtherHolesWithTools( VECTORHOLE& vHoles, const VECTORTOOL& vTools, int nIndTM, int nIndHTM, Hole holeICP, + const Frame3d& frHTM, const Frame3d& frHMTOP, double dDiamToler, int& nDrills) ; + bool MultiHeadVerifyHole( Hole& hole, const ToolData* Tool, double dDiamToler, SelData Id) ; private : double GetSpeed() const diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index 4495130..7ae9c2f 100644 Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ diff --git a/GeoConst.h b/GeoConst.h index 8ff565a..d73c9e6 100644 --- a/GeoConst.h +++ b/GeoConst.h @@ -19,6 +19,7 @@ //----------- Costanti per approssimazioni con polilinee o poliarchi -------- const double LIN_TOL_STD = 0.1 ; const double LIN_TOL_MID = 0.05 ; +const double LIN_TOL_RAW = 0.5 ; const double ANG_TOL_MAX_DEG = 90 ; const double ANG_TOL_STD_DEG = 15 ; const double LIN_FEA_STD = 20 ; diff --git a/Milling.cpp b/Milling.cpp index 1c1c71f..9bcf67f 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2022 +// EgalTech 2015-2023 //---------------------------------------------------------------------------- -// File : Milling.cpp Data : 24.08.22 Versione : 2.4h2 +// File : Milling.cpp Data : 19.12.23 Versione : 2.5l3 // Contenuto : Implementazione gestione fresature. // // @@ -43,9 +43,9 @@ using namespace std ; //------------------------------ Constants ------------------------------------ const double OSC_MIN_LEN = 0.1 ; -const double ELEV_MAX_OFFS = 25.0 ; const double MIN_SAFEDIST = 5.0 ; -const double LIM_DOWN_APPRZ = - 0.5 ; +const double LIM_DOWN_APPRZ = -0.5 ; +const double DELTA_ELEV_RAD = 4.0 ; //------------------------------ Errors -------------------------------------- // 2301 = "Error in Milling : UpdateToolData failed" @@ -2080,69 +2080,30 @@ bool Milling::CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) const { + // default dElev = 0 ; - int nMaxInd = pCompo->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = pCompo->GetCurve( i) ; - // calcolo elevazione - double dCurrElev ; - Point3d ptStart, ptMid, ptEnd ; - pCrvC->GetStartPoint( ptStart) ; - pCrvC->GetMidPoint( ptMid) ; - pCrvC->GetEndPoint( ptEnd) ; - Vector3d vtStartPerp, vtMidPerp, vtEndPerp, vtTg ; - pCrvC->GetStartDir( vtTg) ; - vtStartPerp = vtTg ^ vtTool ; - vtStartPerp.Normalize() ; - vtStartPerp *= dRad ; - pCrvC->GetMidDir( vtTg) ; - vtMidPerp = vtTg ^ vtTool ; - vtMidPerp.Normalize() ; - vtMidPerp *= dRad ; - pCrvC->GetEndDir( vtTg) ; - vtEndPerp = vtTg ^ vtTool ; - vtEndPerp.Normalize() ; - vtEndPerp *= dRad ; - Vector3d vtDepth = vtTool * dDepth ; - // linea centro utensile - if ( GetElevation( m_nPhase, ptStart - vtDepth, ptMid - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) { - if ( dCurrElev > dElev) - dElev = dCurrElev ; - } - else { - m_pMchMgr->SetLastError( 2306, "Error in Milling : Entity GetElevation") ; + // controllo il raggio utensile + double const MIN_RAD = 5 ; + dRad = max( dRad, MIN_RAD) ; + // approssimo la curva con una polilinea + PolyLine PL ; + if ( ! pCompo->ApproxWithLines( LIN_TOL_RAW, ANG_TOL_MAX_DEG, ICurve::APL_SPECIAL, PL)) + return false ; + double const MIN_STEP = 5 ; + double const MAX_STEP = 500 ; + double dStep = Clamp( dRad, MIN_STEP, MAX_STEP) ; + PL.AdjustForMaxSegmentLen( dStep) ; + // calcolo l'elevazione + Point3d ptP ; + bool bFound = PL.GetFirstPoint( ptP) ; + while ( bFound) { + double dPtElev ; + if ( ! GetElevation( m_nPhase, ptP - vtTool * dDepth, vtTool, dRad, vtTool, dPtElev)) return false ; - } - // step laterali - int nStep = Clamp( int( dRad / ELEV_MAX_OFFS + 0.1), 0, 4) + 1 ; - // da una parte - for ( int j = 1 ; j <= nStep ; ++ j) { - double dCoeff = j / double( nStep) ; - if ( GetElevation( m_nPhase, ptStart + dCoeff * vtStartPerp - vtDepth, ptMid + dCoeff * vtMidPerp - vtDepth, - ptEnd + dCoeff * vtEndPerp - vtDepth, vtTool, dCurrElev)) { - if ( dCurrElev > dElev) - dElev = dCurrElev ; - } - else { - m_pMchMgr->SetLastError( 2306, "Error in Milling : Entity GetElevation") ; - return false ; - } - } - // dall'altra parte - for ( int j = 1 ; j <= nStep ; ++ j) { - double dCoeff = j / double( nStep) ; - if ( GetElevation( m_nPhase, ptStart - dCoeff * vtStartPerp - vtDepth, ptMid - dCoeff * vtMidPerp - vtDepth, - ptEnd - dCoeff * vtEndPerp - vtDepth, vtTool, dCurrElev)) { - if ( dCurrElev > dElev) - dElev = dCurrElev ; - } - else { - m_pMchMgr->SetLastError( 2306, "Error in Milling : Entity GetElevation") ; - return false ; - } - } + dElev = max( dElev, dPtElev) ; + bFound = PL.GetNextPoint( ptP) ; } + return true ; } @@ -2321,16 +2282,18 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo pCurve->GetStartDir( vtStart) ; // determino elevazione su inizio percorso di lavoro double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + if ( ! GetElevation( m_nPhase, ptStart, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, false, pCompo, ptP1)) + Vector3d vtDir1 ; + double dCalcStElev = dStElev ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dCalcStElev, false, pCompo, ptP1, vtDir1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; if ( ! vtAppr.Normalize()) - vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + vtAppr = FromNearestHorizontalOrtho( vtTool, vtDir1) ; bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dStElev, dSafeZ) ; // determino se l'inizio dell'attacco è sopra il grezzo bool bGeomAboveStart = GetPointAboveRaw( ptP1, vtTool) ; @@ -2356,10 +2319,8 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { - if ( bAboveStart || dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - } + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) + dStElev = min( dStElev, dNewStElev) ; // se testa sopra, determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione bool bAhUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; @@ -2389,35 +2350,32 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo bUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, GetRadiusForStartEndElevation( false), m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; - } // se non sono sotto, verifico se posso allontanarmi nel piano lama (meglio se in orizzontale) if ( ! bUnderStart) { - Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; - Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; - Vector3d vtAppr2 = ptP1 - ptStart ; - if ( ! vtAppr2.Normalize()) { - if ( ( m_TParams.m_nType & TF_MILL) != 0) - vtAppr2 = -vtStart ; - else - vtAppr2 = CalcCorrDir( pCompo, i) ; - } - double dThick = ( m_TParams.m_nType == TT_MILL_NOTIP ? m_TParams.m_dMaxMat : m_TParams.m_dThick) ; - double dSawStartElev1 = -1, dSawStartElev2 = -1 ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtAppr1, dSawStartElev1) ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtAppr2, dSawStartElev2) ; - if ( dSawStartElev1 > -EPS_SMALL && dSawStartElev2 > -EPS_SMALL) { - bool bFirst = ( dSawStartElev1 < dSawStartElev2) ; + Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) - DELTA_ELEV_RAD * vtTool ; + Point3d ptTestU = ptTest + m_TParams.m_dDiam * ( m_bAboveHead ? Z_AX : -Z_AX) ; + Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, vtDir1) ; + Vector3d vtAppr2 = vtDir1 ; + if ( ! vtAppr2.Normalize()) + vtAppr2 = ( m_TParams.m_nType == TT_MILL_NOTIP ? -vtStart : CalcCorrDir( pCompo, i)) ; + double dThick = ( m_TParams.m_nType == TT_MILL_NOTIP ? m_TParams.m_dMaxMat : m_TParams.m_dThick) + 2 * DELTA_ELEV_RAD ; + double dSawStartElev1, dSawStartElev2 ; + bool bOk1 = GetElevation( m_nPhase, ptTest, ptTestU, vtTool, GetRadiusForStartEndElevation(), dThick, vtAppr1, dSawStartElev1) ; + bool bOk2 = ! AreSameVectorApprox( vtAppr2, vtAppr1) && + GetElevation( m_nPhase, ptTest, ptTestU, vtTool, GetRadiusForStartEndElevation(), dThick, vtAppr2, dSawStartElev2) ; + if ( bOk1 && bOk2) { + bool bFirst = ( dSawStartElev1 < 1.3 * dSawStartElev2) ; vtAppr = ( bFirst ? vtAppr1 : vtAppr2) ; dSawStartElev = ( bFirst ? dSawStartElev1 : dSawStartElev2) ; bSideStart = true ; } - else if ( dSawStartElev1 > -EPS_SMALL) { + else if ( bOk1) { vtAppr = vtAppr1 ; dSawStartElev = dSawStartElev1 ; bSideStart = true ; } - else if ( dSawStartElev2 > -EPS_SMALL) { + else if ( bOk2) { vtAppr = vtAppr2 ; dSawStartElev = dSawStartElev2 ; bSideStart = true ; @@ -2442,7 +2400,7 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo } // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, false, pCompo, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, dCalcStElev, false, pCompo, bSplitArcs)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadIn not computable") ; return false ; } @@ -2496,19 +2454,20 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo pCurve->GetEndDir( vtEnd) ; // elevazione sul punto finale double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + if ( ! GetElevation( m_nPhase, ptEnd, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) dEndElev = dElev ; // aggiungo uscita Point3d ptP1 ; + Vector3d vtDir1 ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, false, pCompo, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, false, pCompo, bSplitArcs, ptP1, vtDir1)) { m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } // determino se la fine dell'uscita è fuori dal grezzo Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; if ( ! vtRetr.Normalize()) - vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + vtRetr = FromNearestHorizontalOrtho( vtTool, vtDir1) ; bool bOutEnd = GetPointOutOfRaw( ptP1, vtTool, vtRetr, dEndElev, dSafeZ) ; // aggiungo retrazione per frese normali e frese che non lavorano di testa già fuori if ( ( m_TParams.m_nType & TF_MILL) != 0 && @@ -2532,10 +2491,8 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { - if ( bAboveEnd || dNewEndElev > EPS_SMALL) - dEndElev = min( dEndElev, dNewEndElev) ; - } + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) + dEndElev = min( dEndElev, dNewEndElev) ; // se testa sopra, determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione bool bAhUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; @@ -2559,35 +2516,33 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo bool bSideEnd = false ; if ( ! bGeomAboveEnd) { bUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), + GetRadiusForStartEndElevation( true), m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; } if ( ! bUnderEnd) { - Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; - Vector3d vtRetr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; - Vector3d vtRetr2 = ptP1 - ptEnd ; - if ( ! vtRetr2.Normalize()) { - if ( ( m_TParams.m_nType & TF_MILL) != 0) - vtRetr2 = vtEnd ; - else - vtRetr2 = CalcCorrDir( pCompo, i + 1) ; - } - double dThick = ( m_TParams.m_nType == TT_MILL_NOTIP ? m_TParams.m_dMaxMat : m_TParams.m_dThick) ; + Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) - DELTA_ELEV_RAD * vtTool ; + Point3d ptTestU = ptTest + m_TParams.m_dDiam * ( m_bAboveHead ? Z_AX : -Z_AX) ; + Vector3d vtRetr1 = FromNearestHorizontalOrtho( vtTool, vtDir1) ; + Vector3d vtRetr2 = vtDir1 ; + if ( ! vtRetr2.Normalize()) + vtRetr2 = ( m_TParams.m_nType == TT_MILL_NOTIP ? vtEnd : CalcCorrDir( pCompo, i + 1)) ; + double dThick = ( m_TParams.m_nType == TT_MILL_NOTIP ? m_TParams.m_dMaxMat : m_TParams.m_dThick) + 2 * DELTA_ELEV_RAD ; double dSawEndElev1, dSawEndElev2 ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtRetr1, dSawEndElev1) ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtRetr2, dSawEndElev2) ; - if ( dSawEndElev1 > -EPS_SMALL && dSawEndElev2 > -EPS_SMALL) { - bool bFirst = ( dSawEndElev1 < dSawEndElev2) ; + bool bOk1 = GetElevation( m_nPhase, ptTest, ptTestU, vtTool, GetRadiusForStartEndElevation(), dThick, vtRetr1, dSawEndElev1) ; + bool bOk2 = ! AreSameVectorApprox( vtRetr2, vtRetr1) && + GetElevation( m_nPhase, ptTest, ptTestU, vtTool, GetRadiusForStartEndElevation(), dThick, vtRetr2, dSawEndElev2) ; + if ( bOk1 && bOk2) { + bool bFirst = ( dSawEndElev1 < 1.3 * dSawEndElev2) ; vtRetr = ( bFirst ? vtRetr1 : vtRetr2) ; dSawEndElev = ( bFirst ? dSawEndElev1 : dSawEndElev2) ; bSideEnd = true ; } - else if ( dSawEndElev1 > -EPS_SMALL) { + else if ( bOk1) { vtRetr = vtRetr1 ; dSawEndElev = dSawEndElev1 ; bSideEnd = true ; } - else if ( dSawEndElev2 > -EPS_SMALL) { + else if ( bOk2) { vtRetr = vtRetr2 ; dSawEndElev = dSawEndElev2 ; bSideEnd = true ; @@ -2676,16 +2631,18 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetStartDir( vtStart) ; // determino elevazione su inizio attacco double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + if ( ! GetElevation( m_nPhase, ptStart, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dStep ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, bInvert, pCompo, ptP1)) + Vector3d vtDir1 ; + double dCalcStElev = dStElev ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dCalcStElev, bInvert, pCompo, ptP1, vtDir1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; if ( ! vtAppr.Normalize()) - vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + vtAppr = FromNearestHorizontalOrtho( vtTool, vtDir1) ; bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dStElev, dSafeZ) ; // determino se l'inizio dell'attacco è sopra il grezzo bool bGeomAboveStart = GetPointAboveRaw( ptP1, vtTool) ; @@ -2713,10 +2670,8 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { - if ( bAboveStart || dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - } + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) + dStElev = min( dStElev, dNewStElev) ; // se testa sopra determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione bool bAhUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; @@ -2751,26 +2706,26 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool // se non sono sotto, verifico se posso allontanarmi nel piano lama (meglio se in orizzontale) if ( ! bUnderStart) { Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; - Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; - Vector3d vtAppr2 = ptP1 - ptStart ; + Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, vtDir1) ; + Vector3d vtAppr2 = vtDir1 ; if ( ! vtAppr2.Normalize()) - vtAppr2 = CalcCorrDir( pCompo, i) ; + vtAppr2 = ( m_TParams.m_nType == TT_MILL_NOTIP ? -vtStart : CalcCorrDir( pCompo, i)) ; double dThick = ( m_TParams.m_nType == TT_MILL_NOTIP ? m_TParams.m_dMaxMat : m_TParams.m_dThick) ; - double dSawStartElev1 = -1, dSawStartElev2 = -1 ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtAppr1, dSawStartElev1) ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtAppr2, dSawStartElev2) ; - if ( dSawStartElev1 > -EPS_SMALL && dSawStartElev2 > -EPS_SMALL) { + double dSawStartElev1, dSawStartElev2 ; + bool bOk1 = GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, dThick, vtAppr1, dSawStartElev1) ; + bool bOk2 = GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, dThick, vtAppr2, dSawStartElev2) ; + if ( bOk1 && bOk2) { bool bFirst = ( dSawStartElev1 < dSawStartElev2) ; vtAppr = ( bFirst ? vtAppr1 : vtAppr2) ; dSawStartElev = ( bFirst ? dSawStartElev1 : dSawStartElev2) ; bSideStart = true ; } - else if ( dSawStartElev1 > -EPS_SMALL) { + else if ( bOk1) { vtAppr = vtAppr1 ; dSawStartElev = dSawStartElev1 ; bSideStart = true ; } - else if ( dSawStartElev2 > -EPS_SMALL) { + else if ( bOk2) { vtAppr = vtAppr2 ; dSawStartElev = dSawStartElev2 ; bSideStart = true ; @@ -2829,7 +2784,7 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, bInvert, pCompo, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, dCalcStElev, bInvert, pCompo, bSplitArcs)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadIn not computable") ; return false ; } @@ -2883,15 +2838,16 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetEndDir( vtEnd) ; // elevazione sul punto finale double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + if ( ! GetElevation( m_nPhase, ptEnd, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) dEndElev = dElev ; // se non c'è attacco a zigzag o a spirale oppure ultimo step, aggiungo uscita Point3d ptP1 = ptEnd ; + Vector3d vtDir1 ; if ( ! IsLeadInHelixOrZigzag() || k == nStep) { if ( k != nStep && GetLeadInType() == MILL_LI_GLIDE) dEndElev = -LIO_ELEV_TOL ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, bInvert, pCompo, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, bInvert, pCompo, bSplitArcs, ptP1, vtDir1)) { m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } @@ -2899,7 +2855,7 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool // determino se la fine dell'uscita è fuori dal grezzo Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; if ( ! vtRetr.Normalize()) - vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + vtRetr = FromNearestHorizontalOrtho( vtTool, vtDir1) ; bool bOutEnd = GetPointOutOfRaw( ptP1, vtTool, vtRetr, dEndElev, dSafeZ) ; // per lame e frese che non lavorano di testa quando ancora dentro aggiungo retrazione se necessaria if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0 || @@ -2918,26 +2874,26 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } if ( ! bUnderEnd) { Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; - Vector3d vtRetr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; - Vector3d vtRetr2 = ptP1 - ptEnd ; + Vector3d vtRetr1 = FromNearestHorizontalOrtho( vtTool, vtDir1) ; + Vector3d vtRetr2 = vtDir1 ; if ( ! vtRetr2.Normalize()) - vtRetr2 = CalcCorrDir( pCompo, i + 1) ; + vtRetr2 = ( m_TParams.m_nType == TT_MILL_NOTIP ? vtEnd : CalcCorrDir( pCompo, i + 1)) ; double dThick = ( m_TParams.m_nType == TT_MILL_NOTIP ? m_TParams.m_dMaxMat : m_TParams.m_dThick) ; double dSawEndElev1, dSawEndElev2 ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtRetr1, dSawEndElev1) ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtRetr2, dSawEndElev2) ; - if ( dSawEndElev1 > -EPS_SMALL && dSawEndElev2 > -EPS_SMALL) { + bool bOk1 = GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, dThick, vtRetr1, dSawEndElev1) ; + bool bOk2 = GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, dThick, vtRetr2, dSawEndElev2) ; + if ( bOk1 && bOk2) { bool bFirst = ( dSawEndElev1 < dSawEndElev2) ; vtRetr = ( bFirst ? vtRetr1 : vtRetr2) ; dSawEndElev = ( bFirst ? dSawEndElev1 : dSawEndElev2) ; bSideEnd = true ; } - else if ( dSawEndElev1 > -EPS_SMALL) { + else if ( bOk1) { vtRetr = vtRetr1 ; dSawEndElev = dSawEndElev1 ; bSideEnd = true ; } - else if ( dSawEndElev2 > -EPS_SMALL) { + else if ( bOk2) { vtRetr = vtRetr2 ; dSawEndElev = dSawEndElev2 ; bSideEnd = true ; @@ -2975,10 +2931,8 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { - if ( bAboveEnd || dNewEndElev > EPS_SMALL) - dEndElev = min( dEndElev, dNewEndElev) ; - } + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) + dEndElev = min( dEndElev, dNewEndElev) ; // se testa sopra, determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione bool bAhUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; @@ -3049,7 +3003,8 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool Vector3d vtStart ; pCompo->GetStartDir( vtStart) ; Point3d ptPs ; - CalcLeadInStart( ptStart, vtStart, vtTool, dElev, false, pCompo, ptPs) ; + Vector3d vtDirs ; + CalcLeadInStart( ptStart, vtStart, vtTool, dElev, false, pCompo, ptPs, vtDirs) ; Vector3d vtCs = CalcCorrDir( pCompo, 0) ; Point3d ptEnd ; pCompo->GetEndPoint( ptEnd) ; @@ -3083,12 +3038,12 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool else if ( m_bAboveHead) { // inizio con sua elevazione e sicurezza double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + if ( ! GetElevation( m_nPhase, ptStart, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; Point3d ptPsr = ptPs + ( dStElev + dSafeZ) * vtTool ; // fine con sua elevazione e sicurezza double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + if ( ! GetElevation( m_nPhase, ptEnd, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) dEndElev = dElev ; Point3d ptPer = ptPe + ( dEndElev + dSafeZ) * vtTool ; // verifica dei punti intermedi @@ -3146,6 +3101,8 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool CalcAndSetCorrAuxDir( pCompo, i) ; // punto inizio attacco Point3d ptP1 ; + Vector3d vtDir1 ; + double dCalcStElev = 0 ; // se speciale e step intermedio if ( bSpecial && j > 1) { ptP1 = ptStart + dStep * vtTool ; @@ -3154,23 +3111,23 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool else { // determino elevazione su inizio attacco double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + if ( ! GetElevation( m_nPhase, ptStart, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; if ( ! bSafeDirLinkStartEnd) dStElev = max( dStElev, j * dStep) ; // determino inizio attacco - if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, false, pCompo, ptP1)) + dCalcStElev = dStElev ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dCalcStElev, false, pCompo, ptP1, vtDir1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; if ( ! vtAppr.Normalize()) - vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + vtAppr = FromNearestHorizontalOrtho( vtTool, vtDir1) ; bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dStElev, dSafeZ) ; // aggiungo approccio per frese normali e frese che non lavorano di testa con attacco opportuno oppure fuori if ( ( m_TParams.m_nType & TF_MILL) != 0 && ( m_TParams.m_nType != TT_MILL_NOTIP || LeadInRawIsOk() || m_bStartOutRaw || bOutStart)) { // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) - Point3d ptP1m = ptP1 - 10 * EPS_SMALL * vtTool ; Vector3d vtEscape = vtTool ; if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { @@ -3178,10 +3135,10 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1m, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { if ( bAboveStartEnd) dStElev = min( dStElev, dNewStElev) ; - else if ( dNewStElev > EPS_SMALL) + else dStElev = max( dStElev, dNewStElev) ; } if ( bOutStartEnd && m_bTiltingTab) @@ -3230,26 +3187,26 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool // se non sono sotto, verifico se posso allontanarmi nel piano lama (meglio se in orizzontale) if ( ! bUnderStart) { Point3d ptTest = ptP1 - MIN_SAFEDIST * vtTool ; - Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; - Vector3d vtAppr2 = ptP1 - ptStart ; + Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, vtDir1) ; + Vector3d vtAppr2 = vtDir1 ; if ( ! vtAppr2.Normalize()) - vtAppr2 = CalcCorrDir( pCompo, i) ; + vtAppr2 = ( m_TParams.m_nType == TT_MILL_NOTIP ? -vtStart : CalcCorrDir( pCompo, i)) ; double dThick = ( m_TParams.m_nType == TT_MILL_NOTIP ? m_TParams.m_dMaxMat : m_TParams.m_dThick) ; - double dSawStartElev1 = -1, dSawStartElev2 = -1 ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick + 2 * MIN_SAFEDIST, vtAppr1, dSawStartElev1) ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick + 2 * MIN_SAFEDIST, vtAppr2, dSawStartElev2) ; - if ( dSawStartElev1 > -EPS_SMALL && dSawStartElev2 > -EPS_SMALL) { + double dSawStartElev1 = 0, dSawStartElev2 = 0 ; + bool bOk1 = GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, dThick, vtAppr1, dSawStartElev1) ; + bool bOk2 = GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, dThick, vtAppr2, dSawStartElev2) ; + if ( bOk1 && bOk2) { bool bFirst = ( dSawStartElev1 < dSawStartElev2) ; vtAppr = ( bFirst ? vtAppr1 : vtAppr2) ; dSawStartElev = ( bFirst ? dSawStartElev1 : dSawStartElev2) ; bSideStart = true ; } - else if ( dSawStartElev1 > -EPS_SMALL) { + else if ( bOk1) { vtAppr = vtAppr1 ; dSawStartElev = dSawStartElev1 ; bSideStart = true ; } - else if ( dSawStartElev2 > -EPS_SMALL) { + else if ( bOk2) { vtAppr = vtAppr2 ; dSawStartElev = dSawStartElev2 ; bSideStart = true ; @@ -3275,7 +3232,7 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, false, pCompo, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, dCalcStElev, false, pCompo, bSplitArcs)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadIn not computable") ; return false ; } @@ -3332,14 +3289,15 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetEndDir( vtEnd) ; // elevazione sul punto finale double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + if ( ! GetElevation( m_nPhase, ptEnd, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) dEndElev = dElev ; if ( ! bSafeDirLinkStartEnd) dEndElev = max( dEndElev, j * dStep) ; // aggiungo uscita Point3d ptP1 ; + Vector3d vtDir1 ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, false, pCompo, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, false, pCompo, bSplitArcs, ptP1, vtDir1)) { m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } @@ -3348,13 +3306,12 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool // determino se la fine dell'uscita è fuori dal grezzo Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; if ( ! vtRetr.Normalize()) - vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + vtRetr = FromNearestHorizontalOrtho( vtTool, vtDir1) ; bool bOutEnd = GetPointOutOfRaw( ptP1, vtTool, vtRetr, dEndElev, dSafeZ) ; // aggiungo retrazione per frese normali e frese che non lavorano di testa già fuori if ( ( m_TParams.m_nType & TF_MILL) != 0 && ( m_TParams.m_nType != TT_MILL_NOTIP || m_bEndOutRaw || bOutEnd)) { // correggo elevazione finale per punto fine uscita (se testa da sopra senza aggregato approccio mai Z-) - Point3d ptP1m = ptP1 - 10 * EPS_SMALL * vtTool ; Vector3d vtEscape = vtTool ; if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { @@ -3362,7 +3319,7 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1m, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { if ( bAboveStartEnd) dEndElev = min( dEndElev, dNewEndElev) ; else if ( dNewEndElev > EPS_SMALL) @@ -3398,26 +3355,26 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } if ( ! bUnderEnd) { Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; - Vector3d vtRetr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; - Vector3d vtRetr2 = ptP1 - ptEnd ; + Vector3d vtRetr1 = FromNearestHorizontalOrtho( vtTool, vtDir1) ; + Vector3d vtRetr2 = vtDir1 ; if ( ! vtRetr2.Normalize()) vtRetr2 = CalcCorrDir( pCompo, i + 1) ; double dThick = ( m_TParams.m_nType == TT_MILL_NOTIP ? m_TParams.m_dMaxMat : m_TParams.m_dThick) ; double dSawEndElev1, dSawEndElev2 ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtRetr1, dSawEndElev1) ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, dThick, vtRetr2, dSawEndElev2) ; - if ( dSawEndElev1 > -EPS_SMALL && dSawEndElev2 > -EPS_SMALL) { + bool bOk1 = GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, dThick, vtRetr1, dSawEndElev1) ; + bool bOk2 = GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, dThick, vtRetr2, dSawEndElev2) ; + if ( bOk1 && bOk2) { bool bFirst = ( dSawEndElev1 < dSawEndElev2) ; vtRetr = ( bFirst ? vtRetr1 : vtRetr2) ; dSawEndElev = ( bFirst ? dSawEndElev1 : dSawEndElev2) ; bSideEnd = true ; } - else if ( dSawEndElev1 > -EPS_SMALL) { + else if ( bOk1) { vtRetr = vtRetr1 ; dSawEndElev = dSawEndElev1 ; bSideEnd = true ; } - else if ( dSawEndElev2 > -EPS_SMALL) { + else if ( bOk2) { vtRetr = vtRetr2 ; dSawEndElev = dSawEndElev2 ; bSideEnd = true ; @@ -3499,12 +3456,14 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCrvC->GetStartDir( vtStart) ; // determino elevazione su inizio attacco double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + if ( ! GetElevation( m_nPhase, ptStart, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = 0 ; dStElev -= dStart ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, false, pCompo, ptP1)) + Vector3d vtDir1 ; + double dCalcStElev = dStElev ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dCalcStElev, false, pCompo, ptP1, vtDir1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo Vector3d vtCorr = CalcCorrDir( pCompo, i) ; @@ -3523,10 +3482,8 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { - if ( bAboveStart || dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - } + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) + dStElev = min( dStElev, dNewStElev) ; // se testa sopra, determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione bool bAhUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; @@ -3553,7 +3510,7 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, false, pCompo, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, dCalcStElev, false, pCompo, bSplitArcs)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadIn not computable") ; return false ; } @@ -3611,12 +3568,13 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCrvC->GetEndDir( vtEnd) ; // elevazione sul punto finale double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + if ( ! GetElevation( m_nPhase, ptEnd, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) dEndElev = dElev ; // aggiungo uscita Point3d ptP1 ; + Vector3d vtDir1 ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, false, pCompo, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, false, pCompo, bSplitArcs, ptP1, vtDir1)) { m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } @@ -3632,10 +3590,8 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { - if ( bAboveEnd || dNewEndElev > EPS_SMALL) - dEndElev = min( dEndElev, dNewEndElev) ; - } + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) + dEndElev = min( dEndElev, dNewEndElev) ; // se testa sopra, determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione bool bAhUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; @@ -3688,12 +3644,14 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetStartDir( vtStart) ; // determino elevazione su inizio attacco double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + if ( ! GetElevation( m_nPhase, ptStart, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; dStElev -= dStart ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, bInvert, pCompo, ptP1)) + Vector3d vtDir1 ; + double dCalcStElev = dStElev ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dCalcStElev, bInvert, pCompo, ptP1, vtDir1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo Vector3d vtCorr = CalcCorrDir( pCompo, ( bInvert ? nMaxInd - i + 1 : i)) ; @@ -3712,10 +3670,8 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { - if ( bAboveStart || dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - } + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) + dStElev = min( dStElev, dNewStElev) ; // se testa sopra, determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione bool bAhUnderStart = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; @@ -3736,7 +3692,7 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, bInvert, pCompo, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, dCalcStElev, bInvert, pCompo, bSplitArcs)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadIn not computable") ; return false ; } @@ -3795,12 +3751,13 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetEndDir( vtEnd) ; // elevazione sul punto finale double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + if ( ! GetElevation( m_nPhase, ptEnd, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) dEndElev = dElev ; // aggiungo uscita Point3d ptP1 ; + Vector3d vtDir1 ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, bInvert, pCompo, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, bInvert, pCompo, bSplitArcs, ptP1, vtDir1)) { m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } @@ -3816,10 +3773,8 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { - if ( bAboveEnd || dNewEndElev > EPS_SMALL) - dEndElev = min( dEndElev, dNewEndElev) ; - } + if ( GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) + dEndElev = min( dEndElev, dNewEndElev) ; // se testa sopra, determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione bool bAhUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; @@ -3924,14 +3879,16 @@ Milling::AddSawZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtT // determino elevazione su inizio attacco double dStElev ; if ( j == 1) { - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + if ( ! GetElevation( m_nPhase, ptStart, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dElev ; } else dStElev = dStep - LIO_ELEV_TOL - 10 * EPS_SMALL ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, bInvert, pCompo, ptP1)) + Vector3d vtDir1 ; + double dCalcStElev = dStElev ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dCalcStElev, bInvert, pCompo, ptP1, vtDir1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo Vector3d vtCorr = CalcCorrDir( pCompo, ( bInvert ? nMaxInd - i + 1 : i)) ; @@ -3962,7 +3919,7 @@ Milling::AddSawZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtT // aggiungo attacco bool bTang = (( ! bInvert && m_Params.m_dLiTang > EPS_SMALL) || ( bInvert && m_Params.m_dLoTang > EPS_SMALL)) ; SetFeed( bTang ? GetStartFeed() : GetTipFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, bInvert, pCompo, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, dCalcStElev, bInvert, pCompo, bSplitArcs)) { m_pMchMgr->SetLastError( 2310, "Error in Milling : LeadIn not computable") ; return false ; } @@ -4001,15 +3958,16 @@ Milling::AddSawZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtT // elevazione sul punto finale double dEndElev ; if ( j == nStep) { - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + if ( ! GetElevation( m_nPhase, ptEnd, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) dEndElev = dElev ; } else dEndElev = - LIO_ELEV_TOL ; // aggiungo uscita Point3d ptP1 ; + Vector3d vtDir1 ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, bInvert, pCompo, bSplitArcs, ptP1)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, dEndElev, bInvert, pCompo, bSplitArcs, ptP1, vtDir1)) { m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } @@ -4297,7 +4255,13 @@ Milling::AddSawBladeSideRetract( const Point3d& ptP, const Vector3d& vtRetr, con if ( ! m_bTiltingTab && vtRetr.z < LIM_DOWN_APPRZ) { Vector3d vtMove = Vector3d( vtTool.x, vtTool.y, 0) ; if ( vtMove.Normalize()) { - Point3d ptP4b = ptP4 + vtMove * ( dEndElev + dSafeZ) ; + double dSawEndElev ; + if ( ! m_bAboveHead || + ! GetAhPointUnderRaw( ptP4, vtTool, m_TParams.m_dTDiam / 2, + GetRadiusForStartEndElevation( false), + m_TParams.m_dLen, true, dSafeZ, vtMove, dSawEndElev)) + dSawEndElev = dEndElev ; + Point3d ptP4b = ptP4 + vtMove * ( dSawEndElev + dSafeZ) ; if ( AddRapidMove( ptP4b) == GDB_ID_NULL) return false ; } @@ -4328,7 +4292,7 @@ Milling::GetLeadInType( void) const //---------------------------------------------------------------------------- bool Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtTool, - double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1) const + double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1, Vector3d& vtDir1) const { // Assegno tipo e parametri int nType = GetLeadInType() ; @@ -4364,15 +4328,53 @@ Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const switch ( nType) { case MILL_LI_NONE : ptP1 = ptStart ; + vtDir1 = -vtStart ; return true ; - case MILL_LI_LINEAR : - case MILL_LI_TG_PERP : + case MILL_LI_LINEAR : { + Vector3d vtPerp = vtStart ; + Vector3d vtRot = OrthoCompo( vtTool, vtStart) ; + vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : -1)) ; + ptP1 = ptStart - vtStart * dTang + vtPerp * dPerp + vtTool * dElev ; + vtDir1 = ptP1 - ptStart ; + if ( ! vtDir1.Normalize()) + return false ; + bool bOk = true ; + // eventuale movimento ortogonale (estensione di inserimento compensazione raggio utensile) + if ( m_Params.m_dLiCompLen > 10 * EPS_SMALL) { + vtDir1 = OrthoCompo( vtDir1, vtTool) ; + bOk = bOk && vtDir1.Normalize() ; + vtDir1.Rotate( vtRot, 0, ( bCcwRot ? -1 : 1)) ; + ptP1 += vtDir1 * m_Params.m_dLiCompLen ; + } + return bOk ; + } + case MILL_LI_TG_PERP : { + Vector3d vtPerp = vtStart ; + Vector3d vtRot = OrthoCompo( vtTool, vtStart) ; + vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : -1)) ; + ptP1 = ptStart - vtStart * dTang + vtPerp * dPerp + vtTool * dElev ; + vtDir1 = ptP1 - ptStart ; + return vtDir1.Normalize() ; + } case MILL_LI_TANGENT : { Vector3d vtPerp = vtStart ; - Vector3d vtRot = vtTool - vtTool * vtStart * vtStart ; - vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; + Vector3d vtRot = OrthoCompo( vtTool, vtStart) ; + vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : -1)) ; ptP1 = ptStart - vtStart * dTang + vtPerp * dPerp + vtTool * dElev ; - return true ; + vtDir1 = ptP1 - ptStart ; + if ( ! vtDir1.Normalize()) + return false ; + bool bOk = true ; + // eventuale movimento ortogonale (estensione di inserimento compensazione raggio utensile) + if ( m_Params.m_dLiCompLen > 10 * EPS_SMALL) { + PtrOwner pCrv( GetArc2PVN( ptStart, ptP1, - vtStart, vtTool)) ; + bOk = bOk && ! IsNull( pCrv) && pCrv->GetEndDir( vtDir1) ; + vtDir1 = OrthoCompo( vtDir1, vtTool) ; + bOk = bOk && vtDir1.Normalize() ; + vtDir1.Rotate( vtRot, 0, ( bCcwRot ? -1 : 1)) ; + ptP1 += vtDir1 * m_Params.m_dLiCompLen ; + } + return bOk ; } case MILL_LI_GLIDE : { @@ -4393,13 +4395,16 @@ Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const } } ptP1 += vtTool * ( vtTool * ( ptStart - ptP1)) + vtTool * dElev ; - return true ; + vtDir1 = ptP1 - ptStart ; + return vtDir1.Normalize() ; } case MILL_LI_ZIGZAG : ptP1 = ptStart ; + vtDir1 = -vtStart ; return true ; case MILL_LI_HELIX : ptP1 = ptStart ; + vtDir1 = -vtStart ; return true ; default : return false ; @@ -4409,12 +4414,13 @@ Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const //---------------------------------------------------------------------------- bool Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, - const Vector3d& vtTool, bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs) + const Vector3d& vtTool, double dStElev, bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs) { // Assegno il tipo int nType = GetLeadInType() ; double dTang = m_Params.m_dLiTang ; double dPerp = m_Params.m_dLiPerp ; + double dElev = min( m_Params.m_dLiElev, dStElev + LIO_ELEV_TOL) ; // se step invertito if ( bInvert) { // va aggiustato se non zigzag o spirale @@ -4444,12 +4450,20 @@ Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& case MILL_LI_NONE : return true ; case MILL_LI_LINEAR : + // eventuale movimento ortogonale (estensione di inserimento compensazione raggio utensile) + if ( m_Params.m_dLiCompLen > 10 * EPS_SMALL) { + Vector3d vtPerp = vtStart ; + Vector3d vtRot = OrthoCompo( vtTool, vtStart) ; + vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; + Point3d ptMid = ptStart - vtStart * dTang + vtPerp * dPerp + vtTool * dElev ; + if ( AddLinearMove( ptMid, MCH_CL_LEADIN) == GDB_ID_NULL) + return false ; + } return ( AddLinearMove( ptStart, MCH_CL_LEADIN) != GDB_ID_NULL) ; case MILL_LI_TG_PERP : { - // direzione perpendicolare Vector3d vtPerp = vtStart ; - Vector3d vtRot = vtTool - vtTool * vtStart * vtStart ; + Vector3d vtRot = OrthoCompo( vtTool, vtStart) ; vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; Point3d ptMid = ptStart + vtPerp * dPerp ; return ( AddLinearMove( ptMid, MCH_CL_LEADIN) != GDB_ID_NULL && @@ -4457,7 +4471,17 @@ Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& } case MILL_LI_TANGENT : { - PtrOwner pCrv( GetArc2PVN( ptStart, ptP1, - vtStart, vtTool)) ; + Point3d ptMid = ptP1 ; + // eventuale movimento ortogonale (estensione di inserimento compensazione raggio utensile) + if ( m_Params.m_dLiCompLen > 10 * EPS_SMALL) { + Vector3d vtPerp = vtStart ; + Vector3d vtRot = OrthoCompo( vtTool, vtStart) ; + vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; + ptMid = ptStart - vtStart * dTang + vtPerp * dPerp + vtTool * dElev ; + if ( AddLinearMove( ptMid, MCH_CL_LEADIN) == GDB_ID_NULL) + return false ; + } + PtrOwner pCrv( GetArc2PVN( ptStart, ptMid, - vtStart, vtTool)) ; if ( IsNull( pCrv)) return false ; pCrv->Invert() ; @@ -4676,15 +4700,22 @@ Milling::CalcLeadOutEnd( const Point3d& ptEnd, const Vector3d& vtEnd, const Vect case MILL_LO_LINEAR : { Vector3d vtPerp = vtEnd ; - Vector3d vtRot = vtTool - vtTool * vtEnd * vtEnd ; + Vector3d vtRot = OrthoCompo( vtTool, vtEnd) ; vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtTool * dElev ; + if ( m_Params.m_dLoCompLen > 10 * EPS_SMALL) { + Vector3d vtPerp2 = vtEnd * dTang + vtPerp * dPerp ; + if ( vtPerp2.Normalize()) { + vtPerp2.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; + ptP1 += vtPerp2 * m_Params.m_dLoCompLen ; + } + } return true ; } case MILL_LO_PERP_TG : { Vector3d vtPerp = vtEnd ; - Vector3d vtRot = vtTool - vtTool * vtEnd * vtEnd ; + Vector3d vtRot = OrthoCompo( vtTool, vtEnd) ; vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; Point3d ptMid = ptEnd + vtPerp * dPerp ; ptP1 = ptMid + vtEnd * dTang + vtTool * dElev ; @@ -4694,9 +4725,16 @@ Milling::CalcLeadOutEnd( const Point3d& ptEnd, const Vector3d& vtEnd, const Vect { // calcolo punto finale dell'uscita Vector3d vtPerp = vtEnd ; - Vector3d vtRot = vtTool - vtTool * vtEnd * vtEnd ; + Vector3d vtRot = OrthoCompo( vtTool, vtEnd) ; vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtTool * dElev ; + if ( m_Params.m_dLoCompLen > 10 * EPS_SMALL) { + Vector3d vtPerp2 = vtEnd * dTang + vtPerp * dPerp ; + if ( vtPerp2.Normalize()) { + vtPerp2.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; + ptP1 += vtPerp2 * m_Params.m_dLoCompLen ; + } + } return true ; } case MILL_LO_GLIDE : @@ -4752,7 +4790,7 @@ Milling::CalcLeadOutEnd( const Point3d& ptEnd, const Vector3d& vtEnd, const Vect //---------------------------------------------------------------------------- bool Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtTool, double dEndElev, - bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs, Point3d& ptP1) + bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs, Point3d& ptP1, Vector3d& vtDir1) { // assegno i parametri int nType = GetLeadOutType() ; @@ -4789,22 +4827,36 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d switch ( nType) { case MILL_LO_NONE : ptP1 = ptEnd ; + vtDir1 = vtEnd ; return true ; case MILL_LO_LINEAR : { Vector3d vtPerp = vtEnd ; - Vector3d vtRot = vtTool - vtTool * vtEnd * vtEnd ; + Vector3d vtRot = OrthoCompo( vtTool, vtEnd) ; vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtTool * dElev ; - return ( AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + vtDir1 = ptP1 - ptEnd ; + if ( ! vtDir1.Normalize()) + return false ; + bool bOk = ( AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + // eventuale movimento ortogonale (estensione di inserimento compensazione raggio utensile) + if ( m_Params.m_dLoCompLen > 10 * EPS_SMALL) { + vtDir1 = OrthoCompo( vtDir1, vtTool) ; + bOk = bOk && vtDir1.Normalize() ; + vtDir1.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; + ptP1 += vtDir1 * m_Params.m_dLoCompLen ; + bOk = bOk && ( AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + } + return bOk ; } case MILL_LO_PERP_TG : { Vector3d vtPerp = vtEnd ; - Vector3d vtRot = vtTool - vtTool * vtEnd * vtEnd ; + Vector3d vtRot = OrthoCompo( vtTool, vtEnd) ; vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; Point3d ptMid = ptEnd + vtPerp * dPerp ; ptP1 = ptMid + vtEnd * dTang + vtTool * dElev ; + vtDir1 = ptP1 - ptMid ; vtDir1.Normalize() ; return ( AddLinearMove( ptMid, MCH_CL_LEADOUT) != GDB_ID_NULL && AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ; } @@ -4812,23 +4864,36 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d { // calcolo punto finale dell'uscita Vector3d vtPerp = vtEnd ; - Vector3d vtRot = vtTool - vtTool * vtEnd * vtEnd ; + Vector3d vtRot = OrthoCompo( vtTool, vtEnd) ; vtPerp.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtTool * dElev ; // inserisco uscita PtrOwner pCrv( GetArc2PVN( ptEnd, ptP1, vtEnd, vtTool)) ; if ( IsNull( pCrv)) return false ; + // assegno direzione finale dell'uscita + if ( ! pCrv->GetEndDir( vtDir1)) + return false ; + bool bOk = true ; // eventuale spezzatura if ( bSplitArcs) { PtrOwner pCompo( CreateCurveComposite()) ; if ( IsNull( pCompo) || ! pCompo->AddCurve( Release( pCrv)) || ! ApproxWithLines( pCompo)) return false ; - return ( AddCurveMove( pCompo, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + bOk = ( AddCurveMove( pCompo, MCH_CL_LEADOUT) != GDB_ID_NULL) ; } else { - return ( AddCurveMove( pCrv, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + bOk = ( AddCurveMove( pCrv, MCH_CL_LEADOUT) != GDB_ID_NULL) ; } + // eventuale movimento ortogonale (estensione di inserimento compensazione raggio utensile) + if ( m_Params.m_dLoCompLen > 10 * EPS_SMALL) { + vtDir1 = OrthoCompo( vtDir1, vtTool) ; + bOk = bOk && vtDir1.Normalize() ; + vtDir1.Rotate( vtRot, 0, ( bCcwRot ? 1 : - 1)) ; + ptP1 += vtDir1 * m_Params.m_dLoCompLen ; + bOk = bOk && ( AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ; + } + return bOk ; } case MILL_LO_GLIDE : { @@ -4876,8 +4941,9 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d return false ; // emetto AddCurveMove( pCrv) ; - // assegno punto finale dell'uscita + // assegno punto e direzione finale dell'uscita pCrv->GetEndPoint( ptP1) ; + pCrv->GetEndDir( vtDir1) ; return true ; } default : @@ -5801,7 +5867,6 @@ Milling::GetRadiusForStartEndElevation( bool bExtra) const if ( ! bExtra) return ( 0.5 * m_TParams.m_dTDiam) ; // aumentato - const double DELTA_ELEV_RAD = 4.0 ; double dDeltaRad = min( DELTA_ELEV_RAD, 0.5 * m_TParams.m_dTDiam) ; return ( 0.5 * m_TParams.m_dTDiam + dDeltaRad) ; } @@ -5814,7 +5879,7 @@ Milling::GetPointOutOfRaw( const Point3d& ptP, const Vector3d& vtTool, const Vec if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { // determino se l'inizio dell'attacco è fuori dal grezzo (considero movimento fresa lungo il suo asse) double dTemp ; - if ( ! GetElevation( m_nPhase, ptP, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dTemp)) + if ( ! GetElevation( m_nPhase, ptP, vtTool, m_TParams.m_dDiam / 2, vtTool, dTemp)) return false ; return ( dTemp < 10 * EPS_SMALL || dTemp > dElev + 10 * EPS_SMALL) ; } @@ -5826,13 +5891,13 @@ Milling::GetPointOutOfRaw( const Point3d& ptP, const Vector3d& vtTool, const Vec Vector3d vtSafe = vtCorr ; vtSafe.z = 0 ; vtSafe.Normalize() ; Point3d ptQ = ptP - ( vtSafe + vtMove) * max( 0.2 * dSafeZ, MIN_SAFEDIST) ; bool bOut = true ; - if ( ! GetElevation( m_nPhase, ptQ, vtTool, 0.5 * m_TParams.m_dDiam, vtMove, dTemp) || dTemp > 10 * EPS_SMALL) { + if ( ! GetElevation( m_nPhase, ptQ, vtTool, m_TParams.m_dDiam / 2, m_TParams.m_dThick, vtMove, dTemp) || dTemp > 10 * EPS_SMALL) { bOut = false ; if ( ! m_bTiltingTab) return false ; } Point3d ptR = ptP + vtTool * m_TParams.m_dThick ; - if ( ! GetElevation( m_nPhase, ptR, vtTool, 0.5 * m_TParams.m_dDiam, vtMove, dTemp) || dTemp > 10 * EPS_SMALL) { + if ( ! GetElevation( m_nPhase, ptR, vtTool, m_TParams.m_dDiam / 2, m_TParams.m_dThick, vtMove, dTemp) || dTemp > 10 * EPS_SMALL) { bOut = false ; if ( ! m_bTiltingTab) return false ; @@ -5840,9 +5905,9 @@ Milling::GetPointOutOfRaw( const Point3d& ptP, const Vector3d& vtTool, const Vec // se tavola basculante (o asse ralla) e non esterno, provo in direzione utensile if ( m_bTiltingTab && ! bOut) { vtMove = vtTool ; - if ( ! GetElevation( m_nPhase, ptQ, vtTool, 0.5 * m_TParams.m_dDiam, vtMove, dTemp) || dTemp > 10 * EPS_SMALL) + if ( ! GetElevation( m_nPhase, ptQ, vtTool, m_TParams.m_dDiam / 2, m_TParams.m_dThick, vtMove, dTemp) || dTemp > 10 * EPS_SMALL) return false ; - if ( ! GetElevation( m_nPhase, ptR, vtTool, 0.5 * m_TParams.m_dDiam, vtMove, dTemp) || dTemp > 10 * EPS_SMALL) + if ( ! GetElevation( m_nPhase, ptR, vtTool, m_TParams.m_dDiam / 2, m_TParams.m_dThick, vtMove, dTemp) || dTemp > 10 * EPS_SMALL) return false ; } return true ; diff --git a/Milling.h b/Milling.h index 93b2273..38fe988 100644 --- a/Milling.h +++ b/Milling.h @@ -106,13 +106,13 @@ class Milling : public Machining bool AddSawBladeSideRetract( const Point3d& ptP, const Vector3d& vtRetr, const Vector3d& vtTool, double dSafeZ, double dSawEndElev, double dEndElev, double dAppr) ; bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtTool, - double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1) const ; + double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1, Vector3d& vtDir1) const ; bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, - const Vector3d& vtTool, bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs) ; + const Vector3d& vtTool, double dStElev, bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs) ; bool CalcLeadOutEnd( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtTool, double dEndElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1) const ; bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtTool, double dEndElev, - bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs, Point3d& ptP1) ; + bool bInvert, const ICurveComposite* pCompo, bool bSplitArcs, Point3d& ptP1, Vector3d& vtDir1) ; bool AdjustOscillParams( const ICurve* pCrv, bool& bPathOscEnable, double& dRampLen, double& dFlatLen) ; bool AddOscillLine( const ICurveLine* pLine, const Vector3d& vtTool, double dRampLen, double dFlatLen) ; bool AddOscillArc( const ICurveArc* pArc, const Vector3d& vtTool, double dRampLen, double dFlatLen) ; diff --git a/Operation.cpp b/Operation.cpp index f7b7c44..018211b 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -317,7 +317,7 @@ Operation::GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, double dElevS = 0 ; // faccio test con un insieme di punti ( !!! sostituire con intersezione tra rettangolo e trimesh !!!) const double STEP = 50 ; - int nStep = max( (int) ceil( ApproxDist( ptP1L, ptP2L) / STEP), 3) ; + int nStep = max( (int) ceil( ApproxDist( ptP1L, ptP2L) / STEP), 2) ; for ( int i = 0 ; i <= nStep ; ++ i) { // calcolo punto di test double dFraz = i / (double) nStep ; @@ -380,90 +380,6 @@ Operation::GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, c return true ; } -#if 1 - -//---------------------------------------------------------------------------- -bool -Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad, - const Vector3d& vtDir, double& dElev) const -{ - if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) - return false ; - // vettore grezzi interessati - INTVECTOR vRawStmId ; - // considero il punto centrale - if ( ! GetElevation( nPhase, ptP, vtDir, dElev, vRawStmId)) - return false ; - // considero più posizioni sulla circonferenza - const int MIN_STEP = 9 ; - const int MAX_STEP = 127 ; - const double LEN_STEP = 12.5 ; - int nStep = Clamp( 2 * int( ( PIGRECO * dRad) / LEN_STEP) + 1, MIN_STEP, MAX_STEP) ; - Vector3d vtRad = FromUprightOrtho( vtTool) * dRad ; - for ( int i = 0 ; i < nStep ; ++ i) { - double dElevT = 0 ; - if ( ! GetElevation( nPhase, ptP + vtRad, vtDir, dElevT, vRawStmId)) - return false ; - dElev = max( dElev, dElevT) ; - // passo alla direzione successiva - vtRad.Rotate( vtTool, ANG_FULL / nStep) ; - } - // considero i vertici che cadono entro il cilindro positivo spazzato dal fondo utensile - for ( auto nRawStmId : vRawStmId) { - // recupero la superficie - const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nRawStmId)) ; - if ( pStm != nullptr) { - // recupero il riferimento della trimesh - Frame3d frStm ; - m_pGeomDB->GetGlobFrame( nRawStmId, frStm) ; - // ciclo sui vertici - Point3d ptV ; - int nV = pStm->GetFirstVertex( ptV) ; - while ( nV != SVT_NULL) { - ptV.ToGlob( frStm) ; - double dDist = ( ptV - ptP) * vtDir ; - if ( dDist > EPS_ZERO) { - if ( AreSameOrOppositeVectorApprox( vtTool, vtDir)) { - Vector3d vtOrtho = OrthoCompo( ptV - ptP, vtDir) ; - if ( vtOrtho.SqLen() < dRad * dRad + EPS_ZERO) - dElev = max( dElev, dDist) ; - } - else { - Vector3d vtOrtho = OrthoCompo( ptV - ptP, vtDir) ; - Vector3d vtMajAx = vtTool ^ vtDir ; vtMajAx.Normalize( EPS_ZERO) ; - Vector3d vtMajOrt = ParallCompo( vtOrtho, vtMajAx) ; - Vector3d vtMinOrt = ( vtOrtho - vtMajOrt) / abs( vtTool * vtDir) ; - if ( vtMajOrt.SqLen() + vtMinOrt.SqLen() < dRad * dRad + EPS_ZERO) - dElev = max( dElev, dDist) ; - } - } - nV = pStm->GetNextVertex( nV, ptV) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad, double dLen, - const Vector3d& vtDir, double& dElev) const -{ - if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) - return false ; - // sopra e sotto - double dElev1, dElev2 ; - if ( ! GetElevation( nPhase, ptP, vtTool, dRad, vtDir, dElev1)) - return false ; - if ( ! GetElevation( nPhase, ptP + dLen * vtTool, vtTool, dRad, vtDir, dElev2)) - return false ; - dElev = max( dElev1, dElev2) ; - return true ; -} - -#else - //---------------------------------------------------------------------------- bool Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad, @@ -508,10 +424,18 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, pCAvTlStm->SetStdTool( dLen, dRad, 0) ; pCAvTlStm->SetSurfTm( *pStm) ; double dDist = 0 ; - // per Collision Avoid il punto di riferimento non è il tip dell'utensile ma il naso mandrino - if ( ! pCAvTlStm->TestPosition( ptPL + dLen * vtToolL, vtToolL, vtDirL, dDist)) - return false ; - if ( dDist > 0) + // non è ammesso un angolo oltre 90deg tra direzione utensile e vettore movimento + if ( vtToolL * vtDirL < 0) { + // il tip utensile è qui il naso mandrino per Collision Avoid + if ( ! pCAvTlStm->TestPosition( ptPL, -vtToolL, vtDirL, dDist)) + return false ; + } + else { + // per Collision Avoid il punto di riferimento non è il tip dell'utensile ma il naso mandrino + if ( ! pCAvTlStm->TestPosition( ptPL + dLen * vtToolL, vtToolL, vtDirL, dDist)) + return false ; + } + if ( dDist > EPS_SMALL) vRawElev.emplace_back( nStmId, dDist) ; } } @@ -541,7 +465,7 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, } b3Tool.Expand( MAX_DIST_RAW) ; // verifico la reale interferenza dell'utensile con i diversi grezzi - for ( int i = 0 ; i < vRawElev.size() ; ++ i) { + for ( int i = 0 ; i < int( vRawElev.size()) ; ++ i) { // box del grezzo BBox3d b3Raw ; m_pGeomDB->GetGlobalBBox( vRawElev[i].first, b3Raw) ; @@ -556,7 +480,30 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, return true ; } -#endif +//---------------------------------------------------------------------------- +bool +Operation::GetElevation( int nPhase, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtTool, double dRad, double dLen, + const Vector3d& vtDir, double& dElev) const +{ + // risultato di default + bool bOk = false ; + dElev = 0 ; + // faccio test sui punti dall'inizio alla fine + const double STEP = 50 ; + int nStep = max( (int) ceil( ApproxDist( ptS, ptE) / STEP), 2) ; + for ( int i = 0 ; i <= nStep ; ++ i) { + // calcolo punto di test + double dFraz = i / (double) nStep ; + Point3d ptP = Media( ptS, ptE, dFraz) ; + // eseguo il calcolo + double dCurrElev ; + if ( GetElevation( nPhase, ptP, vtTool, dRad, dLen, vtDir, dCurrElev)) { + bOk = true ; + dElev = max( dElev, dCurrElev) ; + } + } + return bOk ; +} //---------------------------------------------------------------------------- bool @@ -597,17 +544,17 @@ Operation::GetAhPointUnderRaw( const Point3d& ptP, const Vector3d& vtTool, doubl // determino elevazione del punto rispetto al grezzo a metà altezza Point3d ptTest( ptP.x, ptP.y, dRawCentZ) ; double dNewElev ; - if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev)) + if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev)) dElev = max( dElev, dNewElev) ; // se direzione di fuga quasi orizzontale (max 30 deg) e ingombro utensile rilevante rispetto ad altezza grezzo if ( vtMyDir.z < 0.5 && dToolDimZ > dRawDimZ / 2) { // determino elevazione del punto rispetto al grezzo a metà altezza più metà ingombro utensile ptTest = Point3d( ptP.x, ptP.y, dRawCentZ + dToolDimZ / 2) ; - if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev)) + if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev)) dElev = max( dElev, dNewElev) ; // determino elevazione del punto rispetto al grezzo a metà altezza meno metà ingombro utensile ptTest = Point3d( ptP.x, ptP.y, dRawCentZ - dToolDimZ / 2) ; - if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev)) + if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev)) dElev = max( dElev, dNewElev) ; } return true ; @@ -920,17 +867,17 @@ Operation::GetUhPointAboveRaw( const Point3d& ptP, const Vector3d& vtTool, doubl // determino elevazione del punto rispetto al grezzo a metà altezza Point3d ptTest( ptP.x, ptP.y, dRawCentZ) ; double dNewElev ; - if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev)) + if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev)) dElev = max( dElev, dNewElev) ; // se direzione di fuga quasi orizzontale (max 30 deg) e ingombro utensile rilevante rispetto ad altezza grezzo if ( vtMyDir.z > -0.5 && dToolDimZ > dRawDimZ / 2) { // determino elevazione del punto rispetto al grezzo a metà altezza più metà ingombro utensile ptTest = Point3d( ptP.x, ptP.y, dRawCentZ + dToolDimZ / 2) ; - if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev)) + if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev)) dElev = max( dElev, dNewElev) ; // determino elevazione del punto rispetto al grezzo a metà altezza meno metà ingombro utensile ptTest = Point3d( ptP.x, ptP.y, dRawCentZ - dToolDimZ / 2) ; - if ( GetElevation( m_nPhase, ptTest - 10 * EPS_SMALL * vtTool, vtTool, dToolRadForElev, vtMyDir, dNewElev)) + if ( GetElevation( m_nPhase, ptTest, vtTool, dToolRadForElev, vtMyDir, dNewElev)) dElev = max( dElev, dNewElev) ; } return true ; diff --git a/Operation.h b/Operation.h index f0fbc16..178a3ca 100644 --- a/Operation.h +++ b/Operation.h @@ -84,6 +84,8 @@ class Operation : public IUserObj const Vector3d& vtDir, double& dElev) const ; bool GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad, double dLen, const Vector3d& vtDir, double& dElev) const ; + bool GetElevation( int nPhase, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtTool, double dRad, double dLen, + const Vector3d& vtDir, double& dElev) const ; bool GetAhPointUnderRaw( const Point3d& ptP, const Vector3d& vtTool, double dToolRad, double dToolRadForElev, double dToolLen, bool bIsSaw, double dSafeZ, const Vector3d& vtDir, double& dElev) const ; bool GetUhPointAboveRaw( const Point3d& ptP, const Vector3d& vtTool, double dToolRad, double dToolRadForElev, diff --git a/Pocketing.cpp b/Pocketing.cpp index f70925a..479866c 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -1,7 +1,7 @@ -//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // EgalTech 2017-2022 //---------------------------------------------------------------------------- -// File : Pocketing.cpp Data : 24.08.22 Versione : 2.4h2 +// File : Pocketing.cpp Data : 17.12.23 Versione : 2.5l3 // Contenuto : Implementazione gestione svuotature. // // @@ -32,6 +32,7 @@ #include "/EgtDev/Include/EGkExtText.h" #include "/EgtDev/Include/EGkCurveLocal.h" #include "/EgtDev/Include/EGkDistPointCurve.h" +#include "/EgtDev/Include/EGkPolygonElevation.h" #include "/EgtDev/Include/EGkUserObjFactory.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkStringUtils3d.h" @@ -2051,7 +2052,6 @@ Pocketing::AdjustPocketingSideForVolumePart( ISurfTriMesh* pStmVolPart, const Ve bool Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) { - // recupero gruppo per geometria temporanea ( Gruppo Temp) const string GRP_TEMP = "Temp" ; int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ; @@ -2104,7 +2104,7 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) if ( ! AdjustPocketingSideForVolumePart( pStm_PartVolume, vtTool)) return false ; - // devo calcolare l'Elevazione... + // devo calcolare l'Elevazione... ( devo tenere conto del grezzo, non solo della parte) Frame3d frElevation ; frElevation.Set( ptC, vtTool) ; if ( ! frElevation.IsValid()) @@ -2112,11 +2112,39 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) pStm_PartVolume->ToLoc( frElevation) ; // ricavo quindi il Box BBox3d BBox ; pStm_PartVolume->GetLocalBBox( BBox) ; - // il su cui iniziare a svuotare è quello che si trova a Z minima + // il piano su cui iniziare a svuotare è quello che si trova a Z minima double dZ_min = BBox.GetMin().z ; + // riporto in globale pStm_PartVolume->ToGlob( frElevation) ; - // calcolo l'elevazione massima ( è la lunghezza Z del Box con asse Z uguale a vtTool) - double dElev = BBox.GetDimZ() ; + // calcolo l'elevazione massima su ogni faccia del volume con normale circa - vtTool ( il volume è interno) + double dElev = 0. ; + pStm_PartVolume->Invert() ; // ho curve e normali orientate correttamente + for ( int i = 0 ; i < pStm_PartVolume->GetFacetCount() ; ++ i) { + Vector3d vtN_f ; + if ( ! pStm_PartVolume->GetFacetNormal( i, vtN_f)) + return false ; + if ( ! AreSameVectorEpsilon( vtTool, vtN_f, 5 * EPS_SMALL)) + continue ; + // ricavo le polyLine di bordo + POLYLINEVECTOR vPL ; + if ( ! pStm_PartVolume->GetFacetLoops( i, vPL) || + vPL.empty()) + return false ; + // ricavo le curve Composite associate e calcolo l'elevazione + for ( int j = 0 ; j < int( vPL.size()) ; ++ j) { + PtrOwner pCompo( CreateCurveComposite()) ; + double dCurrElev = 0. ; + if ( IsNull( pCompo) || + ! pCompo->FromPolyLine( vPL[j]) || + ! pCompo->IsValid() || + ! CalcRegionElevation( pCompo, vtTool, 0., + 0.5 * ( m_dDiam_Prec > 0 ? m_dDiam_Prec : m_TParams.m_dDiam), + m_dLen_Prec > 0 ? m_dLen_Prec : m_TParams.m_dLen, dCurrElev)) + return false ; + dElev = max( dElev, dCurrElev) ; + } + } + pStm_PartVolume->Invert() ; // riporto come in orginale // eventuale imposizione massima elevazione da note utente double dMaxElev ; if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) @@ -3267,132 +3295,86 @@ Pocketing::ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion* //---------------------------------------------------------------------------- bool -Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, +Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double dLen, double& dElev) const { + // inizializzo l'elevazione + dElev = 0 ; - // DA ADATTARE ! + // approssimo la curva con una polilinea che uso per creare il poligono equivalente + PolyLine PL ; + if ( ! pCompo->ApproxWithLines( LIN_TOL_RAW, ANG_TOL_MAX_DEG, ICurve::APL_SPECIAL, PL)) + return false ; + Polygon3d pgFacet ; + if ( ! pgFacet.FromPolyLine( PL)) + return false ; + // aggiungo l'affondamento + pgFacet.Translate( -dDepth * vtTool) ; - //// inizializzo l'elevazione - // dElev = 0 ; - //// affondamento come vettore - // Vector3d vtDepth = vtTool * dDepth ; - - //// Offsetto la curva della quantità stabvilità per la ricerca di proiezioni - // OffsetCurve OffsCrv ; - // if ( ! OffsCrv.Make( pCompo, m_dMaxLenRawProj, ICurve::OFF_FILLET)) { - // m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; - // return false ; - // } - // PtrOwner pCompoExtended( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ; - // if ( IsNull( pCompoExtended) || ! pCompoExtended->IsValid()) - // return false ; - - //// Campiono il contorno - // int nMaxInd = pCompoExtended->GetCurveCount() - 1 ; - // for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // // curva corrente - // const ICurve* pCrvC = pCompoExtended->GetCurve( i) ; - // Point3d ptStart ; pCrvC->GetStartPoint( ptStart) ; - // Point3d ptMid ; pCrvC->GetMidPoint( ptMid) ; - // Point3d ptEnd ; pCrvC->GetEndPoint( ptEnd) ; - // // elevazione della curva - // double dCurrElev ; - // if ( GetElevation( m_nPhase, ptStart - vtDepth, ptMid - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) { - // if ( dCurrElev > dElev) - // dElev = dCurrElev ; - // } - // else { - // m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ; - // return false ; - // } - // } - - //// Campiono l'interno con una griglia (uso linee parallele a X) - //// determino il riferimento di base - // Frame3d frPocket ; - // Point3d ptCen ; pCompoExtended->GetCentroid( ptCen) ; - // frPocket.Set( ptCen, vtTool) ; - //// copio il contorno e lo porto nel riferimento - // PtrOwner pCompoL( pCompoExtended->Clone()) ; - // if ( IsNull( pCompoL) || ! pCompoL->ToLoc( frPocket)) { - // m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ; - // return false ; - // } - //// ingombro del contorno in locale - // BBox3d b3Pocket ; - // pCompoL->GetLocalBBox( b3Pocket) ; - // Point3d ptMin ; double dDimX, dDimY, dDimZ ; - // b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; - - //// passi in Y - // const double STEP = m_TParams.m_dDiam ; - // int nYStep = max( int( ceil( ( dDimY - 20 * EPS_SMALL) / STEP)), 2) ; - // double dYStep = ( nYStep > 0 ? ( dDimY - 20 * EPS_SMALL) / nYStep : 0) ; - //// calcolo le linee di svuotatura - // for ( int i = 1 ; i < nYStep ; ++ i) { - // // definisco la linea - // PtrOwner pLine( CreateCurveLine()) ; - // const double EXP_LEN = 1.0 ; - // Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + 10 * EPS_SMALL + i * dYStep, ptMin.z + dDimZ) ; - // if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) { - // m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ; - // return false ; - // } - - // // calcolo la classificazione della curva rispetto al contorno - // IntersCurveCurve intCC( *pLine, *pCompoL) ; - // CRVCVECTOR ccClass ; - // if ( intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) { - // // determino gli intervalli di curva interni - // Intervals inOk ; - // for ( auto& ccOne : ccClass) { - // if ( ccOne.nClass == CRVC_IN) { - // // ricavo punto iniziale e finale - // Point3d ptStart ; - // pLine->GetPointD1D2( ccOne.dParS, ICurve::FROM_PLUS, ptStart) ; - // Point3d ptEnd ; - // pLine->GetPointD1D2( ccOne.dParE, ICurve::FROM_MINUS, ptEnd) ; - // // calcolo la distanza tra questi due punti - // double dDist = Dist( ptStart, ptEnd) ; - // // il tratto interno lo campiono rispetto ad X - // for ( int j = 0 ; j <= int( dDist / STEP) + 1 ; ++ j) { - // Point3d ptCurr ; - // pLine->GetPointD1D2( ccOne.dParS + j * ( ccOne.dParE - ccOne.dParS) / ( dDist / STEP + 1), ICurve::FROM_PLUS, ptCurr) ; - // ptCurr.ToGlob( frPocket) ; - // double dCurrElev ; - // if ( GetElevation( m_nPhase, ptCurr - vtDepth, vtTool, dCurrElev)) { - // if ( dCurrElev > dElev) - // dElev = dCurrElev ; - // } - // else { - // m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ; - // return false ; - // } - // } - // } - // } - // } - // // altrimenti uso tutta la curva - // else { - // Point3d ptStart ; - // pLine->GetStartPoint( ptStart) ; - // ptStart.ToGlob( frPocket) ; - // Point3d ptEnd ; - // pLine->GetEndPoint( ptEnd) ; - // ptEnd.ToGlob( frPocket) ; - // // elevazione della curva - // double dCurrElev ; - // if ( GetElevation( m_nPhase, ptStart - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) { - // if ( dCurrElev > dElev) - // dElev = dCurrElev ; - // } - // else { - // m_pMchMgr->SetLastError( 2408, "Error in Pocketing : Entity GetElevation") ; - // return false ; - // } - // } - // } + // inizializzo elevazioni per ogni grezzo + INTDBLVECTOR vRawElev ; + // ciclo sui grezzi della fase + int nRawId = m_pMchMgr->GetFirstRawPart() ; + while ( nRawId != GDB_ID_NULL) { + // verifico che il grezzo compaia nella fase + if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) { + // recupero la trimesh del grezzo + int nStmId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; + const ISurfTriMesh* pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nStmId)) ; + if ( pStm != nullptr) { + // recupero il riferimento della trimesh + Frame3d frStm ; + m_pGeomDB->GetGlobFrame( nStmId, frStm) ; + // porto il poligono in questo riferimento + Polygon3d pgFacetL = pgFacet ; + pgFacetL.ToLoc( frStm) ; + // calcolo l'elevazione + double dCurrElev ; + if ( ! PolygonElevationInClosedSurfTm( pgFacetL, *pStm, true, dCurrElev)) + return false ; + if ( dCurrElev > EPS_SMALL) + vRawElev.emplace_back( nStmId, dCurrElev) ; + } + } + // passo al grezzo successivo + nRawId = m_pMchMgr->GetNextRawPart( nRawId) ; + } + // se trovate elevazioni + if ( ! vRawElev.empty()) { + // ordino il vettore secondo l'elevazione crescente + sort( vRawElev.begin(), vRawElev.end(), []( const INTDBL& a, const INTDBL& b) + { return a.second < b.second ; }) ; + // box dell'insieme delle posizioni utensile all'inizio + const double MAX_DIST_RAW = 200.0 ; + BBox3d b3Tool ; + pgFacet.GetLocalBBox( b3Tool) ; + b3Tool.Add( b3Tool.GetMin() + dLen * vtTool) ; + b3Tool.Add( b3Tool.GetMax() + dLen * vtTool) ; + if ( vtTool.IsX()) + b3Tool.Expand( 0, dRad, dRad) ; + else if ( vtTool.IsY()) + b3Tool.Expand( dRad, 0, dRad) ; + else if ( vtTool.IsZ()) + b3Tool.Expand( dRad, dRad, 0) ; + else { + double dExpandX = dRad * sqrt( 1 - vtTool.x * vtTool.x) ; + double dExpandY = dRad * sqrt( 1 - vtTool.y * vtTool.y) ; + double dExpandZ = dRad * sqrt( 1 - vtTool.z * vtTool.z) ; + b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ; + } + b3Tool.Expand( MAX_DIST_RAW) ; + // verifico la reale interferenza dell'utensile con i diversi grezzi + for ( int i = 0 ; i < int( vRawElev.size()) ; ++ i) { + // box del grezzo + BBox3d b3Raw ; + m_pGeomDB->GetGlobalBBox( vRawElev[i].first, b3Raw) ; + // confronto con il box dell'utensile nella posizione precedente + BBox3d b3CurrTool = b3Tool ; + b3CurrTool.Translate( dElev * vtTool) ; + if ( b3Raw.Overlaps( b3CurrTool)) + dElev = vRawElev[i].second ; + } + } return true ; } @@ -9508,8 +9490,9 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE // L'algoritmo di allargamento presso i lati aperti è Euristico; io mi estendo a seconda della geometria del // lato aperto al di fuori del volume di svuotatura... Devo controllare di non rovinare delle zone al di fuori di // esso ! - if ( ! pSfrInc->Subtract( *pSfrLimit)) - return false ; + if ( pSfrLimit->IsValid()) + if ( ! pSfrInc->Subtract( *pSfrLimit)) + return false ; // controllo se la curva è un'isola bool bIsIsland = false ; diff --git a/Pocketing.h b/Pocketing.h index 389e6a9..8c95ff6 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -76,7 +76,7 @@ class Pocketing : public Machining bool ResetCurveAllTempProp( ICurve* pCurve) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; - bool CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) const ; + bool CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double dLen, double& dElev) const ; bool VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) ; bool GeneratePocketingPv( int nPathId, const ISurfTriMesh* pStm_PartVolume) ; bool CheckSimpleOverlap( const ICurve* pCrv, const ICurveComposite* pCrvOri, int& nStat, double dToll) ; @@ -317,7 +317,8 @@ class Pocketing : public Machining double m_dDiam_Prec = 0.0 ; // diametro utensile per precedente svuotatura double m_dOffsetR_Prec = 0.0 ; // offset radiale della svuotatura precedente double m_dSideStep_Prec = 0.0 ; // side Step della svuotatura precedente + double m_dLen_Prec = 0.0 ; // Lunghezza del tool precedente bool m_bOrderStepZ = true ; // parametro per ordinare gli step Extra per Z decrescente o meno - bool m_bPocketPlane = true ; // flag per svuotare solo la rimanenza sullo Step Extra + bool m_bPocketPlane = false ; // flag per svuotare solo la rimanenza sullo Step Extra } ; \ No newline at end of file diff --git a/Processor.cpp b/Processor.cpp index aca3ace..4e2d77d 100644 --- a/Processor.cpp +++ b/Processor.cpp @@ -84,6 +84,9 @@ Processor::Run( const string& sOutFile, const string& sInfo) if ( ! VerifySetup()) return false ; + // imposto la fase iniziale come corrente + m_pMchMgr->SetCurrPhase( 1) ; + // evento inizio esecuzione bool bOk = true ; if ( ! OnStart()) { @@ -145,6 +148,9 @@ Processor::Run( const string& sOutFile, const string& sInfo) LOG_ERROR( GetEMkLogger(), "OnEnd error") ; } + // imposto la fase iniziale come corrente + m_pMchMgr->SetCurrPhase( 1) ; + return bOk ; } diff --git a/Simulator.cpp b/Simulator.cpp index d1cb8af..ca9762d 100644 --- a/Simulator.cpp +++ b/Simulator.cpp @@ -47,10 +47,12 @@ static const double MIN_STEP = 1.0 ; static const double MAX_STEP = 100.0 ; static const double MID_STEP = 50.0 ; static const double COLL_STEP = 10. ; +static const double SQ_COEFF_ROT_MOVE = 100. ; static const double COEFF_LIM = 0.999 ; static const double SAFEDIST_STD = 5.0 ; static const int ERR_OUTSTROKE = 1 ; static const int ERR_COLLISION = 11 ; +static const int ERR_TOOL_SEL = 21 ; //---------------------------------------------------------------------------- Simulator::Simulator( void) @@ -997,7 +999,7 @@ Simulator::ManageSingleMove( int& nStatus, double& dMove) double dSqDist = 0 ; for ( size_t i = 0 ; i < m_AxesName.size() ; ++ i) { // coefficiente moltiplicativo per differenziare assi lineari (primi 3) e rotanti (altri) - double dSqCoeff = (( i < 3) ? 1 : 100) ; + double dSqCoeff = (( i < 3) ? 1 : SQ_COEFF_ROT_MOVE) ; dSqDist += dSqCoeff * ( AxesEnd[i] - m_AxesVal[i]) * ( AxesEnd[i] - m_AxesVal[i]) ; } // Calcolo distanza di movimento eventuali assi ausiliari @@ -1006,7 +1008,7 @@ Simulator::ManageSingleMove( int& nStatus, double& dMove) if ( m_AuxAxesLink[i] != 0) continue ; // coefficiente moltiplicativo per differenziare assi lineari e rotanti - double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : 100) ; + double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ; dSqDistAux += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ; } // Considero il massimo delle due distanze @@ -1188,7 +1190,7 @@ Simulator::ManageSingleMove( int& nStatus, double& dMove) double dSqDist = 0 ; for ( int i = 0 ; i < int( m_AuxAxesName.size()) ; ++ i) { // coefficiente moltiplicativo per differenziare assi lineari e rotanti - double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : 100) ; + double dSqCoeff = ( m_AuxAxesLinear[i] ? 1 : SQ_COEFF_ROT_MOVE) ; dSqDist += dSqCoeff * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) * ( m_AuxAxesEnd[i] - m_AuxAxesVal[i]) ; } double dPrevCoeff = m_dCoeff ; @@ -1634,8 +1636,10 @@ Simulator::OnToolSelect( const string& sTool, const string& sHead, int nExit, co m_AuxAxesLink.emplace_back( 0) ; } } - else + else { bOk = false ; + nErr = ERR_TOOL_SEL ; + } } return ( bOk && nErr == 0) ;