diff --git a/Chiseling.cpp b/Chiseling.cpp index 4ddb140..9b2499a 100644 --- a/Chiseling.cpp +++ b/Chiseling.cpp @@ -768,11 +768,31 @@ Chiseling::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in Chiseling : tool name changed (" + diff --git a/Drilling.cpp b/Drilling.cpp index efe5bdc..2ed6e10 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -95,6 +95,7 @@ Drilling::Clone( void) const pDri->m_nStatus = m_nStatus ; pDri->m_nDrillings = m_nDrillings ; pDri->m_bTiltingTab = m_bTiltingTab ; + pDri->m_vtTiltingAx = m_vtTiltingAx ; pDri->m_bAboveHead = m_bAboveHead ; pDri->m_bAggrBottom = m_bAggrBottom ; } @@ -1042,7 +1043,7 @@ Drilling::GenerateHoleCl( int nInd, const SelData& nCircId, const string& sPName } // verifico se tavola basculante bool bTiltTab = false ; - m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab) && bTiltTab) ; + m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab, m_vtTiltingAx) && bTiltTab) ; // verifico se testa da sopra (Z+) m_bAboveHead = m_pMchMgr->GetHeadAbove( m_TParams.m_sHead) ; // verifiche per foro verso il basso @@ -1304,11 +1305,31 @@ Drilling::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in Drilling : tool name changed (" + diff --git a/Drilling.h b/Drilling.h index 299e8aa..41287b0 100644 --- a/Drilling.h +++ b/Drilling.h @@ -100,6 +100,7 @@ class Drilling : public Machining int m_nStatus ; // stato di aggiornamento della lavorazione int m_nDrillings ; // numero di fori generati bool m_bTiltingTab ; // flag utilizzo tavola basculante + Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante bool m_bAboveHead ; // flag utilizzo testa da sopra bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index de5c6ee..27a04f5 100644 Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ diff --git a/EgtMachKernel.vcxproj b/EgtMachKernel.vcxproj index abfd4ac..ac9b300 100644 --- a/EgtMachKernel.vcxproj +++ b/EgtMachKernel.vcxproj @@ -21,7 +21,7 @@ {0BD58222-92F3-48B2-B656-4497D1956874} EgtMachKernel - 10.0.17763.0 + 10.0.20348.0 @@ -102,9 +102,10 @@ true WIN32;_WINDOWS;I_AM_EMK;_DEBUG;%(PreprocessorDefinitions) false - true + false Use CompileAsCpp + stdcpp17 true @@ -166,6 +167,7 @@ copy $(TargetPath) \EgtProg\DllD64 true true false + stdcpp17 false diff --git a/GenMachining.cpp b/GenMachining.cpp index 31a620c..7a8f737 100644 --- a/GenMachining.cpp +++ b/GenMachining.cpp @@ -806,11 +806,31 @@ GenMachining::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in GenMachining : tool name changed (" + diff --git a/Machine.h b/Machine.h index 1560eb0..116cbba 100644 --- a/Machine.h +++ b/Machine.h @@ -95,7 +95,7 @@ class Machine bool GetCurrTableRef1( Point3d& ptRef1) const ; bool GetCurrTableArea1( BBox3d& b3Area1) const ; bool GetCurrTableDeltaRef1( Vector3d& vtDelta1) const ; - bool GetCurrTableIsTilting( bool& bTilting) const ; + bool GetCurrTableIsTilting( bool& bTilting, Vector3d& vtTiltingAx) const ; bool SetCurrTool( const std::string& sTool, const std::string& sHead, int nExit) ; bool ResetCurrTool( void) ; int GetCurrTool( void) const ; diff --git a/MachineCalc.cpp b/MachineCalc.cpp index 775007d..13369ce 100644 --- a/MachineCalc.cpp +++ b/MachineCalc.cpp @@ -167,17 +167,23 @@ Machine::GetCurrTableDeltaRef1( Vector3d& vtDelta1) const //---------------------------------------------------------------------------- bool -Machine::GetCurrTableIsTilting( bool& bTilting) const +Machine::GetCurrTableIsTilting( bool& bTilting, Vector3d& vtTiltingAx) const { // default bTilting = false ; + vtTiltingAx = V_NULL ; // verifico esistenza tavola if ( m_nCalcTabId == GDB_ID_NULL) return false ; // verifico se presente flag che lo forza come tale - bool bTiltingLike ; - if ( m_pGeomDB->GetInfo( m_nCalcTabId, MCH_TILTINGLIKE, bTiltingLike) && bTiltingLike) { + int nTiltingLike ; + if ( m_pGeomDB->GetInfo( m_nCalcTabId, MCH_TILTINGLIKE, nTiltingLike) && nTiltingLike != 0) { bTilting = true ; + switch ( abs( nTiltingLike)) { + default : vtTiltingAx = X_AX ; break ; + case 2 : vtTiltingAx = Y_AX ; break ; + case 3 : vtTiltingAx = Z_AX ; break ; + } return true ; } // recupero gli eventuali assi rotanti della tavola @@ -192,6 +198,7 @@ Machine::GetCurrTableIsTilting( bool& bTilting) const // verifico se asse rotante orizzontale if ( pAx->GetType() == MCH_AT_ROTARY && abs( pAx->GetDir().z) < EPS_SMALL) { bTilting = true ; + vtTiltingAx = pAx->GetDir() ; return true ; } // risalgo lungo la catena diff --git a/Milling.cpp b/Milling.cpp index 76171a3..e1f38af 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -119,10 +119,13 @@ Milling::Clone( void) const pMill->m_dAddedOverlap = m_dAddedOverlap ; pMill->m_nHeadSolCh = m_nHeadSolCh ; pMill->m_bTiltingTab = m_bTiltingTab ; + pMill->m_vtTiltingAx = m_vtTiltingAx ; pMill->m_bAboveHead = m_bAboveHead ; pMill->m_bAggrBottom = m_bAggrBottom ; pMill->m_dCurrOscillLen = m_dCurrOscillLen ; pMill->m_dCurrTabsLen = m_dCurrTabsLen ; + pMill->m_bStartOutRaw = m_bStartOutRaw ; + pMill->m_bEndOutRaw = m_bEndOutRaw ; } catch( ...) { delete pMill ; @@ -247,6 +250,8 @@ Milling::Milling( void) m_bAggrBottom = false ; m_dCurrOscillLen = 0 ; m_dCurrTabsLen = 0 ; + m_bStartOutRaw = false ; + m_bEndOutRaw = false ; } //---------------------------------------------------------------------------- @@ -1087,11 +1092,31 @@ Milling::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ! SameTool( m_TParams, *pTdata, false) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in Milling : tool name changed (" + @@ -1867,7 +1892,7 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) // verifico se tavola basculante bool bTiltTab = false ; - m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab) && bTiltTab) ; + m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab, m_vtTiltingAx) && bTiltTab) ; // verifico se testa da sopra (Z+) m_bAboveHead = m_pMchMgr->GetHeadAbove( m_TParams.m_sHead) ; @@ -1877,6 +1902,12 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) if ( ! VerifyPathFromBottom( pCompo, vtTool)) return false ; + // recupero eventuale flag di inizio forzato fuori dal grezzo + int nStartOutRaw ; + FromString( ExtractInfo( m_Params.m_sUserNotes, "OutRaw="), nStartOutRaw) ; + m_bStartOutRaw = (( nStartOutRaw & 1) != 0) ; + m_bEndOutRaw = (( nStartOutRaw & 2) != 0) ; + // se richiesta anteprima if ( nPvId != GDB_ID_NULL) { // creo gruppo per geometria di anteprima del percorso @@ -2123,7 +2154,8 @@ Milling::VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vt // distanza minima del punto e relativa direzione dal contorno del grezzo Point3d ptP ; double dCurrDist = INFINITO ; Vector3d vtCurrDir ; if ( pCompo->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptP) && - GetMinDistanceFromRawSide( m_nPhase, ptP, dExpand, m_AggrBottom.vtMDir, MCH_AGB_DELTAMAX_MDIR, dCurrDist, vtCurrDir)) { + GetMinDistanceFromRawSide( m_nPhase, ptP, dExpand, m_AggrBottom.vtMDir, MCH_AGB_DELTAMAX_MDIR, dCurrDist, vtCurrDir) && + ! vtCurrDir.IsSmallXY()) { if ( dCurrDist < dMinDist - 10 * EPS_SMALL && find_if( vDir.begin(), vDir.end(), [&](const Vector3d& vtV){ return vtCurrDir * vtV > cos( 15 * DEGTORAD) ; }) == vDir.end()) { // inserisco la direzione tra quelle già esplorate @@ -2281,7 +2313,7 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; if ( ! vtAppr.Normalize()) vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; - bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dElev, dSafeZ) ; + bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dStElev, dSafeZ) ; // determino se l'inizio dell'attacco è sopra il grezzo bool bGeomAboveStart = GetPointAboveRaw( ptP1, vtTool) ; bool bAboveStart = false ; @@ -2293,20 +2325,27 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo } // imposto versore correzione e ausiliario sul punto di partenza CalcAndSetCorrAuxDir( pCompo, i) ; - // aggiungo approccio per frese normali - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // 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-) Vector3d vtEscape = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtEscape.z = 0 ; vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev) && dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - // determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { + if ( bAboveStart || dNewStElev > EPS_SMALL) + 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) ; + // se testa sotto, determino se l'inizio dell'attacco è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; // se attacco a zigzag o a spirale, l'elevazione va nell'attacco if ( IsLeadInHelixOrZigzag()) { ptP1 += vtTool * ( dStElev + LIO_ELEV_TOL) ; @@ -2318,7 +2357,7 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo return false ; } } - // altrimenti, approccio per lame + // altrimenti, approccio per lame e frese che non lavorano di testa else { // verifico di entrare in aria if ( ! bOutStart) { @@ -2327,8 +2366,9 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo bool bUnderStart = false ; bool bSideStart = false ; if ( ! bGeomAboveStart) { - bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), m_TParams.m_dLen, true, dSafeZ, vtAppr, dSawStartElev) ; + 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) @@ -2338,9 +2378,10 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo Vector3d vtAppr2 = ptP1 - ptStart ; if ( ! vtAppr2.Normalize()) 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, vtAppr1, dSawStartElev1) ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtAppr2, dSawStartElev2) ; + 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) ; vtAppr = ( bFirst ? vtAppr1 : vtAppr2) ; @@ -2440,8 +2481,14 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } - // aggiungo retrazione per frese normali - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // determino se la fine dell'uscita è fuori dal grezzo + Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; + if ( ! vtRetr.Normalize()) + vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + 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)) { // determino se la fine dell'uscita è sopra il grezzo bool bAboveEnd = false ; if ( m_bAboveHead) { @@ -2454,29 +2501,30 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo } // correggo elevazione finale per punto fine uscita (se testa da sopra senza aggregato approccio mai Z-) Vector3d vtEscape = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtEscape.z = 0 ; vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev) && dNewEndElev > EPS_SMALL) - dEndElev = min( dEndElev, dNewEndElev) ; - // determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderEnd = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dEndElev) ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { + if ( bAboveEnd || dNewEndElev > EPS_SMALL) + 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) ; + // se testa sotto, determino se l'inizio dell'uscita è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveEnd)) { m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; return false ; } } - // per lame quando è necessario + // per lame e frese che non lavorano di testa quando è necessario else { - // verifico di uscire in aria - Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; - if ( ! vtRetr.Normalize()) - vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; - bool bOutEnd = GetPointOutOfRaw( ptP1, vtTool, vtRetr, dElev, dSafeZ) ; if ( ! bOutEnd) { // verifico se sono sopra bool bGeomAboveEnd = GetPointAboveRaw( ptP1, vtTool) ; @@ -2485,8 +2533,9 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo bool bUnderEnd = false ; bool bSideEnd = false ; if ( ! bGeomAboveEnd) { - bUnderEnd = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, - GetRadiusForStartEndElevation( false), m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; + bUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, + GetRadiusForStartEndElevation( false), + m_TParams.m_dLen, true, dSafeZ, vtRetr, dSawEndElev) ; } if ( ! bUnderEnd) { Point3d ptTest = ptP1 - MIN_SAFEDIST * ( m_bAboveHead ? Z_AX : -Z_AX) ; @@ -2494,9 +2543,10 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo Vector3d vtRetr2 = ptP1 - ptEnd ; 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, vtRetr1, dSawEndElev1) ; - GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtRetr2, 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) ; vtRetr = ( bFirst ? vtRetr1 : vtRetr2) ; @@ -2569,6 +2619,7 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool int nMaxInd = pCompo->GetCurveCount() - 1 ; // ciclo sugli step + bool bOk = true ; for ( int k = 1 ; k <= nStep ; ++ k) { // flag direzione (prima passata indice 1) bool bInvert = ( ( k % 2) == 0) ; @@ -2596,73 +2647,139 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetStartDir( vtStart) ; // determino elevazione su inizio attacco double dStElev ; - if ( k == 1) { - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dStep ; - } - else - dStElev = dStep - LIO_ELEV_TOL - 10 * EPS_SMALL ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dStep ; // determino inizio attacco Point3d ptP1 ; if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, bInvert, pCompo, ptP1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo - Vector3d vtCorr = CalcCorrDir( pCompo, ( bInvert ? nMaxInd + 1 : 0)) ; - bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtCorr, dElev, dSafeZ) ; + Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; + if ( ! vtAppr.Normalize()) + vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtAppr, dStElev, dSafeZ) ; // determino se l'inizio dell'attacco è sopra il grezzo + bool bGeomAboveStart = GetPointAboveRaw( ptP1, vtTool) ; bool bAboveStart = false ; if ( m_bAboveHead) { if ( ! m_bTiltingTab) - bAboveStart = GetPointAboveRaw( ptP1, vtTool) ; + bAboveStart = bGeomAboveStart ; else bAboveStart = bOutStart ; } // imposto versore correzione e ausiliario sul punto di partenza CalcAndSetCorrAuxDir( pCompo, ( bInvert ? nMaxInd - i + 1 : i)) ; - // se primo step aggiungo approccio per frese normali - if ( k == 1 && ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) - Vector3d vtEscape = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { - vtEscape.z = 0 ; - vtEscape.Normalize() ; + // se primo step + if ( k == 1) { + // 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-) + Vector3d vtEscape = vtTool ; + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { + vtEscape.z = 0 ; + 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) ; + } + // 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) ; + // se testa sotto determino se l'inizio dell'attacco è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; + // se attacco a zigzag o a spirale, l'elevazione va nell'attacco + if ( IsLeadInHelixOrZigzag()) { + ptP1 += vtTool * ( dStElev + LIO_ELEV_TOL) ; + dStElev = - LIO_ELEV_TOL ; + } + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart, bAboveStart)) { + m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; + return false ; + } } - double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev) && dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - // determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - // se attacco a zigzag o a spirale, l'elevazione va nell'attacco - if ( IsLeadInHelixOrZigzag()) { - ptP1 += vtTool * ( dStElev + LIO_ELEV_TOL) ; - dStElev = - LIO_ELEV_TOL ; - } - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart, bAboveStart)) { - m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; - return false ; + // altrimenti, approccio per lame e frese che non lavorano di testa + else { + // verifico di entrare in aria + if ( ! bOutStart) { + // verifico se sono sotto + double dSawStartElev = 0 ; + bool bUnderStart = false ; + bool bSideStart = false ; + if ( ! bGeomAboveStart) { + 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()) + 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) ; + vtAppr = ( bFirst ? vtAppr1 : vtAppr2) ; + dSawStartElev = ( bFirst ? dSawStartElev1 : dSawStartElev2) ; + bSideStart = true ; + } + else if ( dSawStartElev1 > -EPS_SMALL) { + vtAppr = vtAppr1 ; + dSawStartElev = dSawStartElev1 ; + bSideStart = true ; + } + else if ( dSawStartElev2 > -EPS_SMALL) { + vtAppr = vtAppr2 ; + dSawStartElev = dSawStartElev2 ; + bSideStart = true ; + } + } + if ( ! bGeomAboveStart && ! bUnderStart && ! bSideStart && bOk) { + m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; + bOk = false ; + } + // aggiungo opportuno approccio + if ( ! AddSawBladeSideApproach( ptP1, vtAppr, dSafeZ, dSawStartElev, dAppr)) { + m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; + return false ; + } + } + else { + // affondo al punto iniziale + SetFlag( 0) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + } } } // altrimenti, affondo al punto iniziale else { - // se lama - if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0) { - SetFlag( 0) ; - if ( k == 1) { - // verifico di entrare in aria - if ( ! bOutStart) { - m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; - return false ; - } - // eseguo affondo - if ( AddRapidStart( ptP1) == GDB_ID_NULL) - return false ; - } - else { - if ( AddRapidMove( ptP1) == GDB_ID_NULL) + // se lama o fresa che non lavora di testa + if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0 || m_TParams.m_nType == TT_MILL_NOTIP) { + SetFeed( GetStartFeed()) ; + // eventuale movimento parallelo all'asse utensile fatto fuori + Point3d ptCurr ; + if ( ! GetCurrPos( ptCurr)) + return false ; + Vector3d vtToolOrt = OrthoCompo( ptP1 - ptCurr, vtTool) ; + if ( vtToolOrt.Len() > 100 * EPS_SMALL) { + if ( AddLinearMove( ptP1 - vtToolOrt) == GDB_ID_NULL) return false ; } + // movimento standard + if ( AddLinearMove( ptP1) == GDB_ID_NULL) + return false ; } // se attacco a zigzag o a spirale, non affondo else if ( IsLeadInHelixOrZigzag()) { @@ -2671,7 +2788,7 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } // altrimenti, affondo in feed opportuna else { - bool bStartFeed = ( bOutStart || m_TParams.m_nType == TT_MILL_NOTIP || m_TParams.m_nType == TT_MILL_POLISHING) ; + bool bStartFeed = ( bOutStart || m_TParams.m_nType == TT_MILL_POLISHING) ; SetFeed( bStartFeed ? GetStartFeed() : GetTipFeed()) ; if ( AddLinearMove( ptP1) == GDB_ID_NULL) return false ; @@ -2733,12 +2850,8 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool pCurve->GetEndDir( vtEnd) ; // elevazione sul punto finale double dEndElev ; - if ( k == nStep) { - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) - dEndElev = dElev ; - } - else - dEndElev = - LIO_ELEV_TOL ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + dEndElev = dElev ; // se non c'è attacco a zigzag o a spirale oppure ultimo step, aggiungo uscita Point3d ptP1 = ptEnd ; if ( ! IsLeadInHelixOrZigzag() || k == nStep) { @@ -2748,8 +2861,66 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool return false ; } } - // se ultimo step aggiungo retrazione per frese normali - if ( k == nStep && ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + // determino se la fine dell'uscita è fuori dal grezzo + Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; + if ( ! vtRetr.Normalize()) + vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + 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 || + ( m_TParams.m_nType == TT_MILL_NOTIP && ! m_bEndOutRaw && ! bOutEnd)) { + if ( ! bOutEnd) { + // verifico se sono sopra + bool bGeomAboveEnd = GetPointAboveRaw( ptP1, vtTool) ; + // verifico se sono sotto + double dSawEndElev = 0 ; + bool bUnderEnd = false ; + bool bSideEnd = false ; + if ( ! bGeomAboveEnd) { + bUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, + GetRadiusForStartEndElevation( false), + 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()) + 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 bFirst = ( dSawEndElev1 < dSawEndElev2) ; + vtRetr = ( bFirst ? vtRetr1 : vtRetr2) ; + dSawEndElev = ( bFirst ? dSawEndElev1 : dSawEndElev2) ; + bSideEnd = true ; + } + else if ( dSawEndElev1 > -EPS_SMALL) { + vtRetr = vtRetr1 ; + dSawEndElev = dSawEndElev1 ; + bSideEnd = true ; + } + else if ( dSawEndElev2 > -EPS_SMALL) { + vtRetr = vtRetr2 ; + dSawEndElev = dSawEndElev2 ; + bSideEnd = true ; + } + } + if ( ! bGeomAboveEnd && ! bUnderEnd && ! bSideEnd && bOk) { + m_pMchMgr->SetLastError( 2324, "Error in Milling : LeadOut must be out of rawpart") ; + bOk = false ; + } + // aggiungo opportuna retrazione + if ( ! AddSawBladeSideRetract( ptP1, vtRetr, dSafeZ, dSawEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; + return false ; + } + } + } + // altrimenti frese e se ultimo step aggiungo retrazione + else if ( k == nStep) { // determino se la fine dell'uscita è sopra il grezzo bool bAboveEnd = false ; if ( m_bAboveHead) { @@ -2762,27 +2933,32 @@ Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } // correggo elevazione finale per punto fine uscita (se testa da sopra senza aggregato approccio mai Z-) Vector3d vtEscape = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtEscape.z = 0 ; vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev) && dNewEndElev > EPS_SMALL) - dEndElev = min( dEndElev, dNewEndElev) ; - // determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderEnd = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dEndElev) ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { + if ( bAboveEnd || dNewEndElev > EPS_SMALL) + 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) ; + // se testa sotto, determino se l'inizio dell'uscita è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveEnd)) { m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; return false ; } } - // per lame non è necessario } } } - return true ; + return bOk ; } //---------------------------------------------------------------------------- @@ -2894,6 +3070,7 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool double dStep = dElev / nStep ; // ciclo sugli step + bool bOk = true ; int nMaxInd = pCompo->GetCurveCount() - 1 ; for ( int k = 1 ; k <= nStep ; ++ k) { int j = ( bStepUp ? nStep - k + 1 : k) ; @@ -2936,27 +3113,34 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, false, pCompo, ptP1)) return false ; // determino se l'inizio dell'attacco è fuori dal grezzo - Vector3d vtCorr = CalcCorrDir( pCompo, i) ; - bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtCorr, dElev, dSafeZ) ; - // aggiungo approccio per frese normali - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + Vector3d vtAppr( vtTool.x, vtTool.y, 0) ; + if ( ! vtAppr.Normalize()) + vtAppr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + 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) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtEscape.z = 0 ; vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1m, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev) && dNewStElev > EPS_SMALL) { + if ( GetElevation( m_nPhase, ptP1m, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { if ( bAboveStartEnd) dStElev = min( dStElev, dNewStElev) ; - else + else if ( dNewStElev > EPS_SMALL) dStElev = max( dStElev, dNewStElev) ; } - // determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + // 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) ; + // se testa sotto, determino se l'inizio dell'attacco è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; // se attacco a zigzag o a spirale, l'elevazione va nell'attacco if ( IsLeadInHelixOrZigzag()) { ptP1 += vtTool * ( dStElev - ( j - 1) * dStep) ; @@ -2977,17 +3161,65 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool } } } - // altrimenti, approccio per lame + // altrimenti, approccio per lame e frese che non lavorano di testa else { // verifico di entrare in aria if ( ! bOutStart) { - m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; - return false ; + // verifico se sono sopra + bool bGeomAboveStart = GetPointAboveRaw( ptP1, vtTool) ; + // verifico se sono sotto + double dSawStartElev = 0 ; + bool bUnderStart = false ; + bool bSideStart = false ; + if ( ! bGeomAboveStart) { + 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 * vtTool ; + Vector3d vtAppr1 = FromNearestHorizontalOrtho( vtTool, ptP1 - ptStart) ; + Vector3d vtAppr2 = ptP1 - ptStart ; + if ( ! vtAppr2.Normalize()) + 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 + 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) { + bool bFirst = ( dSawStartElev1 < dSawStartElev2) ; + vtAppr = ( bFirst ? vtAppr1 : vtAppr2) ; + dSawStartElev = ( bFirst ? dSawStartElev1 : dSawStartElev2) ; + bSideStart = true ; + } + else if ( dSawStartElev1 > -EPS_SMALL) { + vtAppr = vtAppr1 ; + dSawStartElev = dSawStartElev1 ; + bSideStart = true ; + } + else if ( dSawStartElev2 > -EPS_SMALL) { + vtAppr = vtAppr2 ; + dSawStartElev = dSawStartElev2 ; + bSideStart = true ; + } + } + if ( ! bGeomAboveStart && ! bUnderStart && ! bSideStart && bOk) { + m_pMchMgr->SetLastError( 2314, "Error in Milling : LeadIn must be out of rawpart") ; + bOk = false ; + } + // aggiungo opportuno approccio + if ( ! AddSawBladeSideApproach( ptP1, vtAppr, dSafeZ, dSawStartElev, dAppr)) { + m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; + return false ; + } + } + else { + // affondo al punto iniziale + SetFlag( 0) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; } - // affondo al punto iniziale - SetFlag( 0) ; - if ( AddRapidStart( ptP1) == GDB_ID_NULL) - return false ; } } // aggiungo attacco @@ -3060,36 +3292,100 @@ Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool m_pMchMgr->SetLastError( 2311, "Error in Milling : LeadOut not computable") ; return false ; } - // aggiungo retrazione per frese normali (esclusi step intermedi senza retrazione) - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0 && ( j == nStep || bMidRetract)) { - // 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) { - vtEscape.z = 0 ; - vtEscape.Normalize() ; + // se step finale o intermedi con retrazione + if ( j == nStep || bMidRetract) { + // determino se la fine dell'uscita è fuori dal grezzo + Vector3d vtRetr( vtTool.x, vtTool.y, 0) ; + if ( ! vtRetr.Normalize()) + vtRetr = FromNearestHorizontalOrtho( vtTool, ptP1 - ptEnd) ; + 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)) { + vtEscape.z = 0 ; + vtEscape.Normalize() ; + } + double dNewEndElev ; + if ( GetElevation( m_nPhase, ptP1m, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { + if ( bAboveStartEnd ) + dEndElev = min( dEndElev, dNewEndElev) ; + else if ( dNewEndElev > EPS_SMALL) + dEndElev = max( 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) ; + // se testa sotto, determino se l'inizio dell'uscita è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveStartEnd)) { + m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; + return false ; + } } - double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1m, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev) && dNewEndElev > EPS_SMALL) { - if ( bAboveStartEnd) - dEndElev = min( dEndElev, dNewEndElev) ; - else - dEndElev = max( dEndElev, dNewEndElev) ; - } - // determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderEnd = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dEndElev) ; - // aggiungo retrazione - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveStartEnd)) { - m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; - return false ; + // per lame e frese che non lavorano di testa quando è necessario + else { + if ( ! bOutEnd) { + // verifico se sono sopra + bool bGeomAboveEnd = GetPointAboveRaw( ptP1, vtTool) ; + // verifico se sono sotto + double dSawEndElev = 0 ; + bool bUnderEnd = false ; + bool bSideEnd = false ; + if ( ! bGeomAboveEnd) { + bUnderEnd = m_bAboveHead && GetAhPointUnderRaw( ptP1, vtTool, m_TParams.m_dTDiam / 2, + GetRadiusForStartEndElevation( false), + 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()) + 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 bFirst = ( dSawEndElev1 < dSawEndElev2) ; + vtRetr = ( bFirst ? vtRetr1 : vtRetr2) ; + dSawEndElev = ( bFirst ? dSawEndElev1 : dSawEndElev2) ; + bSideEnd = true ; + } + else if ( dSawEndElev1 > -EPS_SMALL) { + vtRetr = vtRetr1 ; + dSawEndElev = dSawEndElev1 ; + bSideEnd = true ; + } + else if ( dSawEndElev2 > -EPS_SMALL) { + vtRetr = vtRetr2 ; + dSawEndElev = dSawEndElev2 ; + bSideEnd = true ; + } + } + if ( ! bGeomAboveEnd && ! bUnderEnd && ! bSideEnd && bOk) { + m_pMchMgr->SetLastError( 2324, "Error in Milling : LeadOut must be out of rawpart") ; + bOk = false ; + } + // aggiungo opportuna retrazione + if ( ! AddSawBladeSideRetract( ptP1, vtRetr, dSafeZ, dSawEndElev, dAppr)) { + m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; + return false ; + } + } } } - // per lame non è necessario } } } - return true ; + return bOk ; } //---------------------------------------------------------------------------- @@ -3168,16 +3464,22 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) Vector3d vtEscape = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtEscape.z = 0 ; vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev) && dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - // determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { + if ( bAboveStart || dNewStElev > EPS_SMALL) + 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) ; + // se testa sotto, determino se l'inizio dell'attacco è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; // approccio al punto iniziale if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart, bAboveStart)) { m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; @@ -3271,16 +3573,22 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool bool bAboveEnd = m_bAboveHead && GetPointAboveRaw( ptP1, vtTool) ; // correggo elevazione finale per punto fine uscita (se testa da sopra senza aggregato approccio mai Z-) Vector3d vtEscape = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtEscape.z = 0 ; vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev) && dNewEndElev > EPS_SMALL) - dEndElev = min( dEndElev, dNewEndElev) ; - // determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderEnd = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dEndElev) ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { + if ( bAboveEnd || dNewEndElev > EPS_SMALL) + 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) ; + // se testa sotto, determino se l'inizio dell'uscita è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveEnd)) { m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; @@ -3334,27 +3642,33 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool Point3d ptP1 ; if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, dStElev, bInvert, pCompo, ptP1)) return false ; + // determino se l'inizio dell'attacco è fuori dal grezzo + Vector3d vtCorr = CalcCorrDir( pCompo, ( bInvert ? nMaxInd - i + 1 : i)) ; + bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtCorr, dElev, dSafeZ) ; + // determino se l'inizio dell'attacco è sopra il grezzo + bool bAboveStart = m_bAboveHead && GetPointAboveRaw( ptP1, vtTool) ; // imposto versore correzione e ausiliario sul punto di partenza CalcAndSetCorrAuxDir( pCompo, ( bInvert ? nMaxInd - i + 1 : i)) ; // aggiungo approccio per frese normali if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) Vector3d vtEscape = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtEscape.z = 0 ; vtEscape.Normalize() ; } double dNewStElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev) && dNewStElev > EPS_SMALL) - dStElev = min( dStElev, dNewStElev) ; - // determino se l'inizio dell'attacco è fuori dal grezzo - Vector3d vtCorr = CalcCorrDir( pCompo, ( bInvert ? nMaxInd - i + 1 : i)) ; - bool bOutStart = GetPointOutOfRaw( ptP1, vtTool, vtCorr, dElev, dSafeZ) ; - // determino se l'inizio dell'attacco è sopra il grezzo - bool bAboveStart = m_bAboveHead && GetPointAboveRaw( ptP1, vtTool) ; - // determino se l'inizio dell'attacco è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderStart = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewStElev)) { + if ( bAboveStart || dNewStElev > EPS_SMALL) + 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) ; + // se testa sotto, determino se l'inizio dell'attacco è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveStart = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dStElev) ; // approccio al punto iniziale if ( ! AddApproach( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, bOutStart, bAboveStart)) { m_pMchMgr->SetLastError( 2309, "Error in Milling : Approach not computable") ; @@ -3443,16 +3757,22 @@ Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool bool bAboveEnd = m_bAboveHead && GetPointAboveRaw( ptP1, vtTool) ; // correggo elevazione finale per punto fine uscita (se testa da sopra senza aggregato approccio mai Z-) Vector3d vtEscape = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < -EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtEscape.z = 0 ; vtEscape.Normalize() ; } double dNewEndElev ; - if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev) && dNewEndElev > EPS_SMALL) - dEndElev = min( dEndElev, dNewEndElev) ; - // determino se l'inizio dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione - bool bUnderEnd = m_bAboveHead && GetPointUnderRaw( ptP1, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dEndElev) ; + if ( GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtEscape, dNewEndElev)) { + if ( bAboveEnd || dNewEndElev > EPS_SMALL) + 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) ; + // se testa sotto, determino se l'inizio dell'uscita è esattamente sopra il grezzo, nel qual caso ricalcolo l'elevazione + bool bUhAboveEnd = ! m_bAboveHead && GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtEscape, dEndElev) ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr, bAboveEnd)) { m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; @@ -3686,16 +4006,18 @@ Milling::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, SetFlag( 0) ; } } - // se testa da sopra senza aggregato da sotto, approccio mai da Z negativo + // se testa da sopra senza aggregato da sotto e non con tavola basculante, approccio mai da Z negativo + // oppure testa da sotto, approccio mai da Z positivo Vector3d vtAppr = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtAppr.z = 0 ; vtAppr.Normalize() ; } // se non sono già sopra il pezzo e sopra attacco c'è spazio per sicurezza o approccio double dSafeDist = ( m_bAggrBottom ? dSafeAggrBottZ : dSafeZ) ; double dElevZ = vtAppr.z * dElev ; - if ( ( ! bAboveStart || m_bTiltingTab) && ! bBottomStart && dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { + if ( ! bAboveStart && ! bBottomStart && dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { // se distanza di sicurezza minore di distanza di inizio if ( dSafeDist < dAppr + 10 * EPS_SMALL) { // 1 -> punto sopra inizio @@ -3787,7 +4109,8 @@ Milling::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, { // se testa da sopra senza aggregato da sotto, retrazione mai da Z negativo Vector3d vtAppr = vtTool ; - if ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) { + if ( ( m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && vtTool.z < - EPS_SMALL) || + ( ! m_bAboveHead && vtTool.z > EPS_SMALL)) { vtAppr.z = 0 ; vtAppr.Normalize() ; } @@ -3803,7 +4126,7 @@ Milling::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, // se non sono già sopra il pezzo e sopra uscita c'è spazio per sicurezza o approccio double dSafeDist = ( m_bAggrBottom ? dSafeAggrBottZ : dSafeZ) ; double dElevZ = vtAppr.z * dElev ; - if ( ( ! bAboveEnd || m_bTiltingTab) && ! bBottomOutStart && dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { + if ( ! bAboveEnd && ! bBottomOutStart && dElev + max( dSafeDist, dAppr) > 10 * EPS_SMALL) { if ( dSafeDist < dAppr + 10 * EPS_SMALL) { // 4 -> movimento di risalita sopra il punto finale SetFeed( GetEndFeed()) ; @@ -5396,7 +5719,7 @@ Milling::GetRadiusForStartEndElevation( bool bExtra) const if ( ! bExtra) return ( 0.5 * m_TParams.m_dTDiam) ; // aumentato - const double DELTA_ELEV_RAD = 2.0 ; + 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) ; } @@ -5432,7 +5755,7 @@ Milling::GetPointOutOfRaw( const Point3d& ptP, const Vector3d& vtTool, const Vec if ( ! m_bTiltingTab) return false ; } - // se tavola rotante (o asse basculante) e non esterno, provo in direzione utensile + // 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) diff --git a/Milling.h b/Milling.h index 4448ff8..6494654 100644 --- a/Milling.h +++ b/Milling.h @@ -145,7 +145,14 @@ class Milling : public Machining bool IsLeadInHelixOrZigzag() const { int nType = GetLeadInType() ; return ( nType == MILL_LI_ZIGZAG || nType == MILL_LI_HELIX) ; } - friend class LeadIOStatus ; + bool LeadInRawIsOk( void) const + { if ( ( m_TParams.m_nType & TF_SAWBLADE) != 0) + return false ; + if ( m_TParams.m_nType != TT_MILL_NOTIP) + return true ; + return ( IsLeadInHelixOrZigzag() && + m_Params.m_dLiTang >= 0.9 * m_TParams.m_dDiam && m_Params.m_dLiElev <= 2) ; } + friend class LeadIOStatus ; private : SELVECTOR m_vId ; // identificativi entità geometriche da lavorare @@ -160,10 +167,13 @@ class Milling : public Machining double m_dAddedOverlap ; // overlap effettivamente aggiunto a percorso chiuso int m_nHeadSolCh ; // criterio scelta soluzione impostato nella testa bool m_bTiltingTab ; // flag utilizzo tavola basculante + Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante bool m_bAboveHead ; // flag utilizzo testa da sopra bool m_bAggrBottom ; // flag utilizzo di aggregato da sotto Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto double m_dCurrOscillLen ; // lunghezza corrente lungo il percorso per l'oscillazione double m_dCurrTabsLen ; // lunghezza corrente lungo il percorso per tabs + bool m_bStartOutRaw ; // flag forzatura inizio fuori dal grezzo + bool m_bEndOutRaw ; // flag forzatura fine fuori dal grezzo } ; \ No newline at end of file diff --git a/Mortising.cpp b/Mortising.cpp index 0d2904b..aaeb17c 100644 --- a/Mortising.cpp +++ b/Mortising.cpp @@ -816,11 +816,31 @@ Mortising::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in Mortising : tool name changed (" + @@ -1537,8 +1557,8 @@ Mortising::GenerateOnePlungeCl( const Point3d& ptStart, const Point3d& ptEnd, co double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() + m_pMchMgr->GetDeltaSafeZ( m_TParams.m_sHead) ; double dStartElev = 0 ; Point3d ptLi = ( nPlunge != MORTISE_PLUNGE_END ? ptStart : ptEnd) + vtTool * dDelta ; - bool bUnderStart = GetPointUnderRaw( ptLi, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStartElev) ; + bool bUnderStart = GetAhPointUnderRaw( ptLi, vtTool, 0, + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStartElev) ; // altrimenti ridetermino elevazione su inizio percorso di lavoro if ( ! bUnderStart) GetElevation( m_nPhase, ptLi, vtTool, GetRadiusForStartEndElevation(), vtTool, dStartElev) ; @@ -1643,8 +1663,8 @@ Mortising::GenerateOnePlungeCl( const Point3d& ptStart, const Point3d& ptEnd, co // determino se la fine dell'uscita è esattamente sotto il grezzo, nel qual caso ricalcolo l'elevazione double dEndElev = 0 ; Point3d ptLo = ptLast + vtTool * dDelta ; - bool bUnderEnd = GetPointUnderRaw( ptLo, vtTool, 0, - GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dEndElev) ; + bool bUnderEnd = GetAhPointUnderRaw( ptLo, vtTool, 0, + GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dEndElev) ; // altrimenti ridetermino elevazione su fine percorso di lavoro if ( ! bUnderEnd) GetElevation( m_nPhase, ptLo, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev) ; diff --git a/Operation.cpp b/Operation.cpp index 4fbe898..3008f45 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -172,13 +172,32 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dElev) const { Vector3d vtNorm ; - return GetElevation( nPhase, ptP, vtDir, dElev, vtNorm) ; + INTVECTOR vRawStmId ; + return GetElevation( nPhase, ptP, vtDir, dElev, vtNorm, vRawStmId) ; } //---------------------------------------------------------------------------- bool Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dElev, Vector3d& vtNorm) const +{ + INTVECTOR vRawStmId ; + return GetElevation( nPhase, ptP, vtDir, dElev, vtNorm, vRawStmId) ; +} + +//---------------------------------------------------------------------------- +bool +Operation::GetElevation( int nPhase, const Point3d& ptP, + const Vector3d& vtDir, double& dElev, INTVECTOR& vRawStmId) const +{ + Vector3d vtNorm ; + return GetElevation( nPhase, ptP, vtDir, dElev, vtNorm, vRawStmId) ; +} + +//---------------------------------------------------------------------------- +bool +Operation::GetElevation( int nPhase, const Point3d& ptP, + const Vector3d& vtDir, double& dElev, Vector3d& vtNorm, INTVECTOR& vRawStmId) const { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -242,11 +261,13 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, } } } - // se c'è triangolo di intersezione, ne recupero la normale + // se c'è triangolo di intersezione, ne recupero la normale e salvo Id del grezzo if ( nTria != SVT_NULL) { Triangle3d Tria ; if ( pStm->GetTriangle( nTria, Tria)) vtNorm = Tria.GetN() ; + if ( find( vRawStmId.begin(), vRawStmId.end(), nStmId) == vRawStmId.end()) + vRawStmId.emplace_back( nStmId) ; } } } @@ -365,32 +386,83 @@ Operation::GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; + // vettore grezzi interessati + INTVECTOR vRawStmId ; // considero il punto centrale - if ( ! GetElevation( nPhase, ptP, vtDir, dElev)) + if ( ! GetElevation( nPhase, ptP, vtDir, dElev, vRawStmId)) return false ; - // considero più direzioni sulla circonferenza - const int MIN_STEP = 8 ; - const double LEN_STEP = 25 ; - int nStep = max( int( ( 2 * PIGRECO * dRad) / LEN_STEP), MIN_STEP) ; + // 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) { - // esploro 4 posizioni sulle direzioni - for ( int j = 1 ; j <= 8 ; j *= 2) { - double dElevT = 0 ; - if ( ! GetElevation( nPhase, ptP + vtRad / j, vtDir, dElevT)) - return false ; - dElev = max( dElev, dElevT) ; - } + 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() ; + 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::GetPointUnderRaw( const Point3d& ptP, const Vector3d& vtTool, double dToolRad, double dToolRadForElev, - double dToolLen, bool bIsSaw, double dSafeZ, const Vector3d& vtDir, double& dElev) const +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 ; +} + +//---------------------------------------------------------------------------- +bool +Operation::GetAhPointUnderRaw( const Point3d& ptP, const Vector3d& vtTool, double dToolRad, double dToolRadForElev, + double dToolLen, bool bIsSaw, double dSafeZ, const Vector3d& vtDir, double& dElev) const { // punto a metà lunghezza utensile Point3d ptQ = ptP + vtTool * dToolLen / 2 ; @@ -710,6 +782,66 @@ Operation::GetSignedDistFromStmRaw( int nPhase, const Point3d ptP, const Vector3 } +//---------------------------------------------------------------------------- +bool +Operation::GetUhPointAboveRaw( const Point3d& ptP, const Vector3d& vtTool, double dToolRad, double dToolRadForElev, + double dToolLen, bool bIsSaw, double dSafeZ, const Vector3d& vtDir, double& dElev) const +{ + // punto a metà lunghezza utensile + Point3d ptQ = ptP + vtTool * dToolLen / 2 ; + // box di ingombro dell'utensile + BBox3d b3Tool ; + b3Tool.Set( ptP) ; + b3Tool.Add( ptQ) ; + double dExpandX = sqrt( 1 - vtTool.x * vtTool.x) * dToolRadForElev ; + double dExpandY = sqrt( 1 - vtTool.y * vtTool.y) * dToolRadForElev ; + double dExpandZ = sqrt( 1 - vtTool.z * vtTool.z) * dToolRadForElev ; + b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ; + // extra ingombro reale in Z + double dExtraZ = sqrt( 1 - vtTool.z * vtTool.z) * dToolRad ; + // direzione di fuga per l'elevazione + Vector3d vtMyDir = vtDir ; + if ( bIsSaw || vtMyDir.z > EPS_SMALL) + vtMyDir.z = 0 ; + vtMyDir.Normalize() ; + // determino la posizione del punto rispetto al grezzo + // ciclo sui grezzi + int nRawId = m_pMchMgr->GetFirstRawPart() ; + while ( nRawId != GDB_ID_NULL) { + // se il grezzo compare nella fase + if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) { + int nStmId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; + BBox3d b3Raw ; + m_pGeomDB->GetGlobalBBox( nStmId, b3Raw) ; + b3Raw.Expand( 0.5 * dSafeZ, 0.5 * dSafeZ, 0) ; + if ( ! b3Raw.IsEmpty() && b3Raw.OverlapsXY( b3Tool) && ptP.z - dExtraZ > b3Raw.GetMax().z + 10 * EPS_SMALL) { + double dRawCentZ = ( b3Raw.GetMin().z + b3Raw.GetMax().z) / 2 ; + double dRawDimZ = b3Raw.GetMax().z - b3Raw.GetMin().z ; + double dToolDimZ = b3Tool.GetMax().z - b3Tool.GetMin().z ; + // 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)) + 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)) + 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)) + dElev = max( dElev, dNewElev) ; + } + return true ; + } + } + nRawId = m_pMchMgr->GetNextRawPart( nRawId) ; + } + return false ; +} + //---------------------------------------------------------------------------- bool Operation::GetDistanceFromRawSide( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dDist) const @@ -1292,7 +1424,7 @@ Operation::ApproxWithArcsIfUseful( ICurveComposite* pCompo, bool bCareTempProp) for ( int j = 0 ; j < pCC->GetCurveCount() ; ++ j) pCC->SetCurveTempProp( j, vInt[i].second) ; // reinserisco nel vettore di curve - vpCrvs.back().Set( Release( pCC)) ; + vpCrvs.back().Set( pCC) ; } } // riassemblo la curva e assegno le opportune proprietà @@ -3092,7 +3224,7 @@ Operation::CalcDeltaZForHeadRotation( const DBLVECTOR& vAxStart, const DBLVECTOR bool Operation::GetExtraZ( const DBLVECTOR& vAx1, const Vector3d& vtTool1, const DBLVECTOR& vAx2, const Vector3d& vtTool2, - double dSafeZ, double& dExtraZ) const + double dHomeZ, double& dExtraZ) const { // Recupero macchina corrente Machine* pMch = ( m_pMchMgr != nullptr ? m_pMchMgr->GetCurrMachine() : nullptr) ; @@ -3114,12 +3246,12 @@ Operation::GetExtraZ( const DBLVECTOR& vAx1, const Vector3d& vtTool1, if ( SpecialGetMaxZ( vAx1, vtTool1, vAx2, vtTool2, dMaxZ)) { // se caso standard if ( ! bZHomeDown) { - dExtraZ = min( dMaxZ, dAxZmax) - dSafeZ ; + dExtraZ = min( dMaxZ, dAxZmax) - dHomeZ ; return ( dExtraZ > EPS_SMALL) ; } // altrimenti caso con posizione sicura in basso (teste da sotto) else { - dExtraZ = max( dMaxZ, dAxZmin) - dSafeZ ; + dExtraZ = max( dMaxZ, dAxZmin) - dHomeZ ; return ( dExtraZ < EPS_SMALL) ; } } @@ -3144,14 +3276,14 @@ Operation::GetExtraZ( const DBLVECTOR& vAx1, const Vector3d& vtTool1, if ( ! bZHomeDown) { double dZmax ; pMch->GetCurrAxisMax( 2, dZmax) ; - dExtraZ = min( vdVal[0], dZmax - dSafeZ) ; + dExtraZ = min( vdVal[0], dZmax - dHomeZ) ; return ( dExtraZ > EPS_SMALL) ; } // altrimenti caso con posizione sicura in basso (teste da sotto) else { double dZmin ; pMch->GetCurrAxisMin( 2, dZmin) ; - dExtraZ = max( vdVal[0], dZmin - dSafeZ) ; + dExtraZ = max( vdVal[0], dZmin - dHomeZ) ; return ( dExtraZ < EPS_SMALL) ; } } diff --git a/Operation.h b/Operation.h index ef49997..56a72e7 100644 --- a/Operation.h +++ b/Operation.h @@ -72,6 +72,10 @@ class Operation : public IUserObj const Vector3d& vtDir, double& dElev) const ; bool GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dElev, Vector3d& vtNorm) const ; + bool GetElevation( int nPhase, const Point3d& ptP, + const Vector3d& vtDir, double& dElev, INTVECTOR& vRawStmId) const ; + bool GetElevation( int nPhase, const Point3d& ptP, + const Vector3d& vtDir, double& dElev, Vector3d& vtNorm, INTVECTOR& vRawStmId) const ; bool GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtDir, double& dElev) const ; bool GetElevation( int nPhase, const Point3d& ptP1, const Point3d& ptP2, const Point3d& ptP3, @@ -82,6 +86,12 @@ class Operation : public IUserObj double dToolLen, bool bIsSaw, double dSafeZ, const Vector3d& vtDir, double& dElev) const ; bool GetSignedDistFromStmRaw( int nPhase, const Point3d ptP, const Vector3d vtDir, double& dDist, Vector3d& vtNorm) const ; + bool GetElevation( int nPhase, const Point3d& ptP, 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, + double dToolLen, bool bIsSaw, double dSafeZ, const Vector3d& vtDir, double& dElev) const ; bool GetDistanceFromRawSide( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dDist) const ; bool GetMinDistanceFromRawSide( int nPhase, const Point3d& ptP, double dExpand, double& dDist, Vector3d& vtDir) const ; @@ -134,7 +144,7 @@ class Operation : public IUserObj bool CalcDeltaZForHeadRotation( const DBLVECTOR& vAxStart, const DBLVECTOR& vAxEnd, double& dDeltaZ) const ; bool GetExtraZ( const DBLVECTOR& vAx1, const Vector3d& vtTool1, const DBLVECTOR& vAx2, const Vector3d& vtTool2, - double dSafeZ, double& dExtraZ) const ; + double dHomeZ, double& dExtraZ) const ; bool SpecialGetMaxZ( const DBLVECTOR& vAx1, const Vector3d& vtTool1, const DBLVECTOR& vAx2, const Vector3d& vtTool2, double& dMaxZ) const ; diff --git a/Pocketing.cpp b/Pocketing.cpp index e782b15..d4d6d7b 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -128,6 +128,7 @@ Pocketing::Clone( void) const pPock->m_nStatus = m_nStatus ; pPock->m_nPockets = m_nPockets ; pPock->m_bTiltingTab = m_bTiltingTab ; + pPock->m_vtTiltingAx = m_vtTiltingAx ; pPock->m_bAboveHead = m_bAboveHead ; pPock->m_bAggrBottom = m_bAggrBottom ; pPock->m_bOpenOutRaw = m_bOpenOutRaw ; @@ -933,11 +934,31 @@ Pocketing::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in Pocketing : tool name changed (" + @@ -7657,7 +7678,7 @@ Pocketing::ComputePolishingPath( ICurveComposite* pMCrv, ICurveComposite* pRCrv, // calcolo il collegamento con biarchi (garantendo che non esca dalla svuotatura) PtrOwner pCrvLink( CreateCurveComposite()) ; if ( CalcBoundedLinkWithBiArcs( ptStart, vtStart, ptEnd, vtEnd, pCrvBound, pCrvLink)) { - vLinks[i].Set( Release( pCrvLink)) ; + vLinks[i].Set( pCrvLink) ; } else { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; @@ -8148,8 +8169,13 @@ Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector } // correzione per punto sotto il grezzo con testa normale da sopra double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; - bool bUnderEnd = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetPointUnderRaw( ptP1, vtN, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtN, dElev) ; + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP1, vtN, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtN, dElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP1, vtN, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtN, dElev) ; + bOppositeHome = ( bAhUnderRaw || bUhAboveRaw) ; return true ; } case POCKET_LO_GLIDE : @@ -8186,11 +8212,17 @@ Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector } // correzione per punto sotto il grezzo con testa normale da sopra double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; - bool bUnderEnd = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetPointUnderRaw( ptP1, vtN, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtN, dElev) ; + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP1, vtN, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtN, dElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP1, vtN, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtN, dElev) ; + bOppositeHome = ( bAhUnderRaw || bUhAboveRaw) ; return true ; } default : + bOppositeHome = false ; return false ; } @@ -8200,8 +8232,9 @@ Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector double Pocketing::GetRadiusForStartEndElevation( void) const { - const double DELTA_ELEV_RAD = 20.0 ; - return ( 0.5 * m_TParams.m_dTDiam + min( 0.25 * m_TParams.m_dTDiam, DELTA_ELEV_RAD)) ; + 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) ; } //---------------------------------------------------------------------------- @@ -9727,7 +9760,7 @@ Pocketing::AjustCurveForProjRawOnFace( const ICurveLine* pL1, ICurveLine* pL2, c ptJ2A = vPtTan[1] ; ptJ2B = vPtTan[1] ; break ; - default: + default: break ; } diff --git a/Pocketing.h b/Pocketing.h index e6ffe12..013ca7d 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -247,7 +247,7 @@ class Pocketing : public Machining if ( m_Params.m_nLeadInType != POCKET_LI_GLIDE && m_Params.m_dLiElev < 10 * EPS_SMALL) return POCKET_LI_NONE ; return m_Params.m_nLeadInType ; } - int LeadInIsOk( void) const + bool LeadInRawIsOk( void) const { if ( m_TParams.m_nType != TT_MILL_NOTIP) return true ; return (( GetLeadInType() == POCKET_LI_ZIGZAG || GetLeadInType() == POCKET_LI_HELIX) && @@ -258,7 +258,7 @@ class Pocketing : public Machining return m_Params.m_nLeadOutType ; } private : - SELVECTOR m_vId ; // identificativi entità geometriche da lavorare + SELVECTOR m_vId ; // identificativi entit� geometriche da lavorare PocketingData m_Params ; // parametri lavorazione ToolData m_TParams ; // parametri utensile double m_dTHoldBase ; // posizione base del porta-utensile @@ -268,6 +268,7 @@ class Pocketing : public Machining int m_nStatus ; // stato di aggiornamento della lavorazione int m_nPockets ; // numero di percorsi di svuotatura generati bool m_bTiltingTab ; // flag utilizzo tavola basculante + Vector3d m_vtTiltingAx ; // versore direzione eventuale asse basculante bool m_bAboveHead ; // flag utilizzo testa da sopra bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto Vector3d m_vtAggrBottom ; // vettore direzione ausiliaria aggregato da sotto diff --git a/SawFinishing.cpp b/SawFinishing.cpp index 1445694..f107165 100644 --- a/SawFinishing.cpp +++ b/SawFinishing.cpp @@ -795,11 +795,31 @@ SawFinishing::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in SawFinishing : tool name changed (" + @@ -967,7 +987,7 @@ SawFinishing::AdjustGeometry( int nAuxId) // verifiche sull'ampiezza dell'angolo al centro degli eventuali archi VerifyArcs( pCompo) ; // reinserisco nella curva originale - pGuide.Set( Release( pCompo)) ; + pGuide.Set( pCompo) ; } // deve iniziare in comune con la prima sezione ed essere ivi perpendicolare Vector3d vtGdDir ; diff --git a/SawRoughing.cpp b/SawRoughing.cpp index 3515a4f..03ea200 100644 --- a/SawRoughing.cpp +++ b/SawRoughing.cpp @@ -753,11 +753,31 @@ SawRoughing::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in SawRoughing : tool name changed (" + @@ -925,7 +945,7 @@ SawRoughing::AdjustGeometry( int nAuxId) // verifiche sull'ampiezza dell'angolo al centro degli eventuali archi VerifyArcs( pCompo) ; // reinserisco nella curva originale - pGuide.Set( Release( pCompo)) ; + pGuide.Set( pCompo) ; } // deve iniziare in comune con la prima sezione ed essere ivi perpendicolare Vector3d vtGdDir ; diff --git a/Sawing.cpp b/Sawing.cpp index d231dc7..ed2cccb 100644 --- a/Sawing.cpp +++ b/Sawing.cpp @@ -1025,11 +1025,31 @@ Sawing::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in Sawing : tool name changed (" + @@ -1478,7 +1498,7 @@ Sawing::ProcessPath( int nPathId, int nPvId, int nClId) ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nCopyId)) ; // unisco le parti allineate - if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL)) + if ( ! pCompo->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL)) return false ; // eventuale inversione percorso @@ -3812,29 +3832,40 @@ bool Sawing::CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide, int nWorkSide, double dSideAng, Vector3d& vtTool, Vector3d& vtCorr) { - // Versore fresa : annullo la componente in Z e normalizzo - vtTool = vtTang ; - vtTool.z = 0 ; - if ( ! vtTool.Normalize()) + // Direzione tangente nel piano XY + Vector3d vtXYTg = vtTang ; + vtXYTg.z = 0 ; + double dLenXYTg = vtXYTg.Len() ; + if ( dLenXYTg < EPS_SMALL) return false ; - // ruoto attorno a Zglob+ a seconda del lato mandrino + vtXYTg /= dLenXYTg ; + // se direzione tangente inclinata in Z e SideAng non nullo devo calcolare la vera tangente nel piano XY + if ( abs( vtTang.z) > EPS_SMALL && abs( dSideAng) > EPS_ANG_SMALL) { + double dSinDelta = vtTang.z * tan( dSideAng * DEGTORAD) / dLenXYTg ; + double dCosDelta = sqrt( 1 - dSinDelta * dSinDelta) ; + if ( nHeadSide == SAW_HS_LEFT) + vtXYTg.Rotate( Z_AX, dCosDelta, dSinDelta) ; + else + vtXYTg.Rotate( Z_AX, dCosDelta, -dSinDelta) ; + } + + // Versore fresa : ruoto direzione nel piano XY attorno a Zglob+ a seconda del lato mandrino + vtTool = vtXYTg ; if ( nHeadSide == SAW_HS_LEFT) vtTool.Rotate( Z_AX, 0, 1) ; else vtTool.Rotate( Z_AX, 0, -1) ; - // Versore correzione + // Versore correzione : se lama sbandata devo aggiustare vtCorr = Z_AX ; - - // Se lama sbandata if ( abs( dSideAng) > EPS_ANG_SMALL) { if ( nWorkSide == SAW_WS_RIGHT) { - vtTool.Rotate( vtTang, - dSideAng) ; - vtCorr.Rotate( vtTang, - dSideAng) ; + vtTool.Rotate( vtXYTg, - dSideAng) ; + vtCorr.Rotate( vtXYTg, - dSideAng) ; } else { - vtTool.Rotate( vtTang, dSideAng) ; - vtCorr.Rotate( vtTang, dSideAng) ; + vtTool.Rotate( vtXYTg, dSideAng) ; + vtCorr.Rotate( vtXYTg, dSideAng) ; } } diff --git a/Simulator.cpp b/Simulator.cpp index 31211e0..c71e09b 100644 --- a/Simulator.cpp +++ b/Simulator.cpp @@ -72,6 +72,7 @@ Simulator::Simulator( void) m_nAuxEInd = 0 ; m_nExit = 0 ; m_dTDiam = 0 ; + m_bCutOnTip = false ; m_dSafeDist = SAFEDIST_STD ; m_nAxesMask = 0 ; m_bEnabAxes = true ; @@ -134,6 +135,7 @@ Simulator::Start( bool bFirst) m_sHead.clear() ; m_nExit = 0 ; m_dTDiam = 0 ; + m_bCutOnTip = false ; ResetInterpolation() ; ResetAxes() ; ResetAuxAxes() ; @@ -470,6 +472,9 @@ Simulator::UpdateTool( bool bFirst, int& nErr) m_sHead = sHead ; m_nExit = nExit ; m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ; + double dTipFeed = 0 ; + m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ; + m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ; // ripristino la lavorazione corrente m_pMchMgr->SetCurrMachining( nCurrMchId) ; // aggiorno gli assi macchina @@ -509,6 +514,9 @@ Simulator::UpdateTool( bool bFirst, int& nErr) m_sHead = sHead ; m_nExit = nExit ; m_pMchMgr->TdbGetCurrToolParam( TPA_DIAM, m_dTDiam) ; + double dTipFeed = 0 ; + m_pMchMgr->TdbGetCurrToolParam( TPA_TIPFEED, dTipFeed) ; + m_bCutOnTip = ( dTipFeed > EPS_MACH_LEN_PAR) ; // aggiorno gli assi macchina if ( ! UpdateAxes()) return false ; @@ -1038,21 +1046,28 @@ Simulator::ManageSingleMove( int& nStatus, double& dMove) } m_pMachine->SetAxisPos( m_AuxAxesName[j], dVal) ; } - // eseguo eventuale collision check - bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ; - } - // se non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill - if ( nMoveType != 0 || ! NeedCollisionCheck()) { - for ( int i = 0 ; i < int( m_VmTool.size()) ; ++ i) { - Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ; - bool bOkF = GetHeadCurrPosDirAux( m_VmTool[i].sHead, m_VmTool[i].nExit, ptNoseF, vtDirF, vtAuxF) ; - for ( int j = 0 ; j < int( m_VmId.size()) ; ++ j) { - Frame3d frVzmF ; - bOkF = m_pGeomDB->GetGlobFrame( m_VmId[j], frVzmF) && bOkF ; - ExecLineVmill( m_VmId[j], i, m_VmTool[i].dTdOffs, m_VmTool[i].dAdOffs, - vPtNoseI[i], vVtDirI[i], vVtAuxI[i], vFrVzmI[j], ptNoseF, vtDirF, vtAuxF, frVzmF) ; + // se non è rapido o non c'è verifica collisioni, eseguo eventuale Vmill + if ( nMoveType != 0 || ! NeedCollisionCheck()) { + for ( int j = 0 ; j < int( m_VmTool.size()) ; ++ j) { + Point3d ptNoseF ; Vector3d vtDirF ; Vector3d vtAuxF ; + bool bOkF = GetHeadCurrPosDirAux( m_VmTool[j].sHead, m_VmTool[j].nExit, ptNoseF, vtDirF, vtAuxF) ; + for ( int k = 0 ; k < int( m_VmId.size()) ; ++ k) { + Frame3d frVzmF ; + bOkF = m_pGeomDB->GetGlobFrame( m_VmId[k], frVzmF) && bOkF ; + ExecLineVmill( m_VmId[k], j, m_VmTool[j].dTdOffs, m_VmTool[j].dAdOffs, + vPtNoseI[j], vVtDirI[j], vVtAuxI[j], vFrVzmI[k], ptNoseF, vtDirF, vtAuxF, frVzmF) ; + // se ultimo utensile, salvo riferimento per prossimo inizio + if ( j == int( m_VmTool.size()) - 1) + vFrVzmI[k] = frVzmF ; + } + // aggiorno prossimo inizio + vPtNoseI[j] = ptNoseF ; + vVtDirI[j] = vtDirF ; + vVtAuxI[j] = vtAuxF ; } } + // eseguo eventuale collision check + bCollCheck = bCollCheck && ExecCollisionCheck( nCdInd, nObjInd, nMoveType) ; } } // Eseguo movimento su arco @@ -1284,6 +1299,15 @@ Simulator::ExecLineVmill( int nVmId, int nCurrTool, double dVmTdOffs, double dVm ") Pf=(" + ToString( ptHfL) + ") Vf=(" + ToString( vtHfL) + ") Af=(" + ToString( vtAfL) + ")" ; LOG_DBG_INFO( GetEMkLogger(), sOut.c_str()) } + // Se utensile che non lavora di testa + if ( ! m_bCutOnTip) { + // se movimento di testa, non eseguo asportazione + Vector3d vtDirM = Media( vtHiL, vtHfL) ; + vtDirM.Normalize() ; + double dAxMove = ( ptHfL - ptHiL) * vtDirM ; + if ( dAxMove < -EPS_SMALL && dAxMove < -0.5 * abs( dAxMove)) + return true ; + } // Eseguo return pVZM->MillingStep( nCurrTool, ptHiL, vtHiL, vtAiL, ptHfL, vtHfL, vtAfL) ; } diff --git a/Simulator.h b/Simulator.h index 21808d5..3c340c6 100644 --- a/Simulator.h +++ b/Simulator.h @@ -158,6 +158,7 @@ class Simulator std::string m_sHead ; // nome della testa corrente int m_nExit ; // indice dell'uscita corrente double m_dTDiam ; // diametro dell'utensile corrente + bool m_bCutOnTip ; // flag capacità di lavorare di testa dell'utensile corrente INTVECTOR m_VmId ; // vettore identificativi Zmap per Virtual Milling INTVECTOR m_CdId ; // vettore identificativi Zmap per Collision Detection VMTVECTOR m_VmTool ; // vettore utensili attivi per virtual milling diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 1a06026..f750af5 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -800,11 +800,31 @@ SurfFinishing::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in SurfFinishing : tool name changed (" + @@ -1359,7 +1379,7 @@ SurfFinishing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) return false ; // sostituisco la vecchia curva con la nuova - vpCrvs[k].Set( Release( pCompo )) ; + vpCrvs[k].Set( pCompo) ; } // ciclo sulle curve elementari int nMaxInd = vpCrvs[k]->GetCurveCount() - 1 ; @@ -1720,7 +1740,7 @@ SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) return false ; // sostituisco la vecchia curva con la nuova - pMCrv.Set( Release( pCompo )) ; + pMCrv.Set( pCompo) ; } // ciclo sulle curve elementari int nMaxInd = pMCrv->GetCurveCount() - 1 ; @@ -1883,7 +1903,7 @@ SurfFinishing::CalcSpiral( const ICurveComposite* pCompo, bool bSplitArcs, if ( bNextOk) { // sistemo per prossimo step dCurrRad = dRad ; - pOffs.Set( Release( pNextOffs)) ; + pOffs.Set( pNextOffs) ; pCurr = Get( pOffs) ; // nuovo valore pari allo step dOffs = GetSideStep() ; @@ -2083,6 +2103,7 @@ SurfFinishing::GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) con double SurfFinishing::GetRadiusForStartEndElevation( void) const { - const double DELTA_ELEV_RAD = 20.0 ; - return ( 0.5 * m_TParams.m_dTDiam + DELTA_ELEV_RAD) ; + 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) ; } diff --git a/ToolData.h b/ToolData.h index b7aaedb..dbdb20d 100644 --- a/ToolData.h +++ b/ToolData.h @@ -72,7 +72,7 @@ struct ToolData //---------------------------------------------------------------------------- inline bool -SameTool( const ToolData& Td1, const ToolData& Td2) +SameTool( const ToolData& Td1, const ToolData& Td2, bool bAlsoNameTcPosHeadExit = true) { const double EPS_TOOL_LEN = 10 * EPS_SMALL ; const double EPS_TOOL_ANG = 10 * EPS_ANG_SMALL ; @@ -80,11 +80,11 @@ SameTool( const ToolData& Td1, const ToolData& Td2) const double EPS_FEED = 0.5 ; const double EPS_ABSORP = 0.5 ; return ( Td1.m_Uuid == Td2.m_Uuid && - Td1.m_sName == Td2.m_sName && + ( Td1.m_sName == Td2.m_sName || ! bAlsoNameTcPosHeadExit) && Td1.m_sDraw == Td2.m_sDraw && - Td1.m_sTcPos == Td2.m_sTcPos && - Td1.m_sHead == Td2.m_sHead && - Td1.m_nExit == Td2.m_nExit && + ( Td1.m_sTcPos == Td2.m_sTcPos || ! bAlsoNameTcPosHeadExit) && + ( Td1.m_sHead == Td2.m_sHead || ! bAlsoNameTcPosHeadExit) && + ( Td1.m_nExit == Td2.m_nExit || ! bAlsoNameTcPosHeadExit) && Td1.m_nCorr == Td2.m_nCorr && Td1.m_nType == Td2.m_nType && abs( Td1.m_dMaxSpeed - Td2.m_dMaxSpeed) < EPS_SPEED && diff --git a/WaterJetting.cpp b/WaterJetting.cpp index ecc1393..6cb4e90 100644 --- a/WaterJetting.cpp +++ b/WaterJetting.cpp @@ -964,11 +964,31 @@ WaterJetting::UpdateToolData( bool* pbChanged) const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; if ( pTdata == nullptr) return false ; - // verifico se sono diversi (ad esclusione del nome) - m_TParams.m_sName = pTdata->m_sName ; - bool bChanged = ! SameTool( m_TParams, *pTdata) ; + // salvo posizione TC, testa e uscita originali + string sOrigTcPos = m_TParams.m_sTcPos ; + string sOrigHead = m_TParams.m_sHead ; + int nOrigExit = m_TParams.m_nExit ; + // verifico se sono diversi (ad esclusione di nome, posizione TC, testa e uscita) + bool bChanged = ( ! SameTool( m_TParams, *pTdata, false)) ; // aggiorno comunque i parametri m_TParams = *pTdata ; + // se definito attrezzaggio, aggiorno i parametri che ne possono derivare + string sTcPos ; string sHead ; int nExit ; + if ( m_pMchMgr->GetCurrSetupMgr().GetToolData( m_TParams.m_sName, sTcPos, sHead, nExit)) { + if ( sOrigTcPos != sTcPos || + sOrigHead != sHead || + nOrigExit != nExit) + bChanged = true ; + m_TParams.m_sTcPos = sTcPos ; + m_TParams.m_sHead = sHead ; + m_TParams.m_nExit = nExit ; + } + else { + if ( sOrigTcPos != pTdata->m_sTcPos || + sOrigHead != pTdata->m_sHead || + nOrigExit != pTdata->m_nExit) + bChanged = true ; + } // eventuali segnalazioni if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { string sInfo = "Warning in WaterJetting : tool name changed (" + @@ -1941,7 +1961,7 @@ WaterJetting::AddLeadInPreview( const ICurveComposite* pCompo, ISurfFlatRegion* { PtrOwner pLine( CreateCurveLine()) ; if ( IsNull( pLine) || ! pLine->Set( ptP1, ptStart)) return false ; - pCrv.Set( Release( pLine)) ; + pCrv.Set( pLine) ; } break ; case WJET_LI_TANGENT : pCrv.Set( GetArc2PVN( ptStart, ptP1, - vtStart, vtN)) ; @@ -2010,7 +2030,7 @@ WaterJetting::AddLeadOutPreview( const ICurveComposite* pCompo, ISurfFlatRegion* Point3d ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp ; if ( IsNull( pLine) || ! pLine->Set( ptEnd, ptP1)) return false ; - pCrv.Set( Release( pLine)) ; + pCrv.Set( pLine) ; } break ; case WJET_LO_TANGENT : { // calcolo punto finale dell'uscita