diff --git a/CamData.cpp b/CamData.cpp index 61a2754..a2d284e 100644 --- a/CamData.cpp +++ b/CamData.cpp @@ -349,7 +349,7 @@ CamData::GetDrawPolyLines( POLYLINELIST& lstPL) const PL.AddUPoint( 1, ptTip) ; // aggiungo simil-freccia Frame3d frF ; - if ( m_vtTool. IsSmall()) + if ( m_vtTool. IsSmall() || AreSameOrOppositeVectorApprox( m_vtTool, m_vtCorr)) frF.Set( ptTip, m_vtCorr) ; else frF.Set( ptTip, m_vtCorr, m_vtTool) ; @@ -378,7 +378,7 @@ CamData::GetDrawPolyLines( POLYLINELIST& lstPL) const PL.AddUPoint( 1, ptTip) ; // aggiungo simil-freccia Frame3d frF ; - if ( m_vtTool. IsSmall()) + if ( m_vtTool. IsSmall() || AreSameOrOppositeVectorApprox( m_vtTool, m_vtAux)) frF.Set( ptTip, m_vtAux) ; else frF.Set( ptTip, m_vtAux, m_vtTool) ; 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/Disposition.cpp b/Disposition.cpp index e126a10..ed8e763 100644 --- a/Disposition.cpp +++ b/Disposition.cpp @@ -1353,7 +1353,8 @@ Disposition::SpecialApply( bool bRecalc) bOk = bOk && pMch->LuaResetGlobVar( EMC_VAR) ; // segnalo errori ed esco if ( ! bOk || nErr > 0) { - m_nShifts = - 1 ; + if ( m_nShifts != -1) + m_nShifts = -2 ; string sOut = sMsg ; if ( IsEmptyOrSpaces( sOut)) sOut = " Error in " + ON_SPECIAL_APPLY + " (" + ToString( nErr) + ")" ; @@ -1393,7 +1394,7 @@ Disposition::SpecialUpdate( void) // se disposizione vuota, esco if ( m_nShifts <= 0) { - if ( m_nShifts < 0) + if ( m_nShifts == -2) m_pMchMgr->SetWarning( 2052, "Warning in Disposition : No shifts") ; return true ; } diff --git a/Disposition.h b/Disposition.h index 8f0b7e3..7ce4cd9 100644 --- a/Disposition.h +++ b/Disposition.h @@ -56,14 +56,14 @@ class Disposition : public Operation { return true ; } bool Save( int nBaseId, STRVECTOR& vString) const override ; bool Load( const STRVECTOR& vString, int nBaseGdbId) override ; - + public : // Operation - int GetType( void) const override - { return OPER_DISP ; } - bool IsEmpty( void) const override - { return ( m_nShifts == 0) ; } + int GetType( void) const override + { return OPER_DISP ; } + bool IsEmpty( void) const override + { return ( m_nShifts == 0) ; } bool UpdateStatus( int nModif) override - { m_nStatus |= nModif ; return true ; } + { m_nStatus |= nModif ; return true ; } protected : // Operation const std::string& GetToolName( void) const override ; @@ -71,7 +71,7 @@ class Disposition : public Operation int GetExitNbr( void) const override ; const std::string& GetToolTcPos( void) const override ; int GetSolCh( void) const override - { return 0 ; } + { return 0 ; } bool NeedPrevHome( void) const override ; public : @@ -111,6 +111,8 @@ class Disposition : public Operation bool GetToolData( std::string& sName, std::string& sHead, int& nExit, std::string& sTcPos) const ; bool GetSomeByHand( void) const { return m_bSomeByHand ; } + bool IsWithTool( void) + { return ( m_nShifts != -1) ;} private : bool InsertMoveInfoInList( int nRawId, int nType, const Point3d& ptP, int nFlag) ; diff --git a/Drilling.cpp b/Drilling.cpp index 6cfba16..4657c42 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -126,6 +126,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 ; } @@ -1580,7 +1581,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 @@ -1842,11 +1843,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 c66c998..6ba5c19 100644 --- a/Drilling.h +++ b/Drilling.h @@ -111,6 +111,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..a683cea 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/Generator.cpp b/Generator.cpp index 8457ed1..264d683 100644 --- a/Generator.cpp +++ b/Generator.cpp @@ -19,6 +19,7 @@ #include "OutputConst.h" #include "/EgtDev/Include/EMkDllMain.h" #include "/EgtDev/Include/EGnFileUtils.h" +#include "/EgtDev/Include/EGnGetKeyData.h" using namespace std ; @@ -46,19 +47,31 @@ Generator::Init( MachMgr* pMchMgr) bool Generator::Run( const string& sCncFile, const string& sInfo) { - // verifico sia abilitato dalla licenza - bool bEnabled = false ; - if ( GetEMkNetHwKey()) { - bEnabled = true ; - } - else { - unsigned int nOpt1, nOpt2 ; - int nOptExpDays ; + // Controllo della licenza + unsigned int nOpt1, nOpt2 ; + int nOptExpDays ; + int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, + nOpt1, nOpt2, nOptExpDays) ; + if ( ! GetEMkNetHwKey()) int nRet = GetKeyOptions( GetEMkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nOptExpDays) ; - bEnabled = ( nRet == KEY_OK && ( nOpt1 & KEYOPT_EMK_NC_OFF) == 0) ; - } - if ( bEnabled) { + + // Verifica della abilitazione + bool bMinTime = false ; + if ( nOptExpDays >= GetMinDay()) + bMinTime = true ; + bool bCurrTime = false ; + if ( nOptExpDays >= GetCurrDay()) + bCurrTime = true ; + bool bKey = false ; + if ( nRet == KEY_OK) + bKey = true ; + bool bOption = false ; + if ( ( nOpt1 & KEYOPT_EMK_NC_OFF) == 0) + bOption = true ; + + // Esecuzione + if ( bMinTime && bCurrTime && bKey && bOption) { // emetto info di log { string sOut = "Generator Run : " + sCncFile ; @@ -79,6 +92,11 @@ Generator::Run( const string& sCncFile, const string& sInfo) return bOk ; } + // cancello l'eventuale file di uscita (e anche il file errore) + EraseFile( sCncFile) ; + string sErrFile = ChangeFileExtension( sCncFile, ERR_EXT) ; + EraseFile( sErrFile) ; + // Generazione non abilitata m_pMchMgr->SetLastError( 1000, "NC_OFF") ; std::string sErr = "Warning on Key (MKC/NCO)" ; diff --git a/GeoCalc.cpp b/GeoCalc.cpp index 6ca4d62..2f0aa47 100644 --- a/GeoCalc.cpp +++ b/GeoCalc.cpp @@ -82,7 +82,7 @@ GetRotationComponent( const Vector3d& vtDir1, double dComp, const Vector3d& vtDi double dDenom = dT0uv * dSinG ; double dNumer = dComp - dT0w * dCosG ; // due angoli possibili - if ( abs( dDenom) > abs( dNumer)) { + if ( abs( dDenom) > abs( dNumer) + SIN_EPS_ANG_ZERO) { double dDeltaAngRad = acos( dNumer / dDenom) ; dAng1Deg = ( dOffsAngRad + dDeltaAngRad) * RADTODEG ; dAng2Deg = ( dOffsAngRad - dDeltaAngRad) * RADTODEG ; diff --git a/Machine.h b/Machine.h index 1560eb0..2a19ccd 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 ; @@ -125,6 +125,8 @@ class Machine bool GetAllCurrAxesToken( STRVECTOR& vAxToken) const ; bool GetCurrAxisMin( int nInd, double& dMin) const ; bool GetCurrAxisMax( int nInd, double& dMax) const ; + bool GetCurrAxisOffset( int nInd, double& dOffset) const ; + bool GetCurrAxisInvert( int nInd, bool& bInvert) const ; bool GetCurrAxisHomePos( int nInd, double& dHome) const ; bool GetAllCurrAxesHomePos( DBLVECTOR& vAxHomeVal) const ; const Frame3d& GetCurrLinAxesFrame( void) const diff --git a/MachineCalc.cpp b/MachineCalc.cpp index 775007d..6f6b963 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 @@ -1002,7 +1009,7 @@ Machine::GetMyAngles( const Vector3d& vtDirT, const Vector3d& vtDirA, // calcolo primo angolo di rotazione per seconda soluzione bool bDet2 = true ; if ( nStat == 2) { - if ( ! vtDirH2.GetRotation( vtDirTn, vtAx1, dAngA2, bDet2) ) + if ( ! vtDirH2.GetRotation( vtDirTn, vtAx1, SIN_EPS_ANG_SMALL, dAngA2, bDet2)) nStat = 1 ; else { // se indeterminato, provo a determinarlo con la direzione ausiliaria @@ -1025,7 +1032,7 @@ Machine::GetMyAngles( const Vector3d& vtDirT, const Vector3d& vtDirA, // calcolo primo angolo di rotazione per prima soluzione bool bDet1 = true ; if ( nStat >= 1) { - if ( ! vtDirH1.GetRotation( vtDirTn, vtAx1, dAngA1, bDet1) ) + if ( ! vtDirH1.GetRotation( vtDirTn, vtAx1, SIN_EPS_ANG_SMALL, dAngA1, bDet1)) nStat = 0 ; else { // se indeterminato, provo a determinarlo con la direzione ausiliaria @@ -1820,6 +1827,52 @@ Machine::GetCurrAxisMax( int nInd, double& dMax) const return false ; } +//---------------------------------------------------------------------------- +bool +Machine::GetCurrAxisOffset( int nInd, double& dOffset) const +{ + int nLinAxes = int( m_vCalcLinAx.size()) ; + int nRotAxes = int( m_vCalcRotAx.size()) ; + if ( nInd >= 0 && nInd < nLinAxes) { + Axis* pAx = GetAxis( m_vCalcLinAx[nInd].nGrpId) ; + if ( pAx == nullptr) + return false ; + dOffset = pAx->GetOffset() ; + return true ; + } + else if ( nInd >= nLinAxes && nInd < nLinAxes + nRotAxes) { + Axis* pAx = GetAxis( m_vCalcRotAx[nInd-nLinAxes].nGrpId) ; + if ( pAx == nullptr) + return false ; + dOffset = pAx->GetOffset() ; + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +Machine::GetCurrAxisInvert( int nInd, bool& bInvert) const +{ + int nLinAxes = int( m_vCalcLinAx.size()) ; + int nRotAxes = int( m_vCalcRotAx.size()) ; + if ( nInd >= 0 && nInd < nLinAxes) { + Axis* pAx = GetAxis( m_vCalcLinAx[nInd].nGrpId) ; + if ( pAx == nullptr) + return false ; + bInvert = pAx->GetInvert() ; + return true ; + } + else if ( nInd >= nLinAxes && nInd < nLinAxes + nRotAxes) { + Axis* pAx = GetAxis( m_vCalcRotAx[nInd-nLinAxes].nGrpId) ; + if ( pAx == nullptr) + return false ; + bInvert = pAx->GetInvert() ; + return true ; + } + return false ; +} + //---------------------------------------------------------------------------- bool Machine::GetCurrAxisHomePos( int nInd, double& dHome) const diff --git a/Machining.cpp b/Machining.cpp index 1b55645..7436a6f 100644 --- a/Machining.cpp +++ b/Machining.cpp @@ -287,12 +287,12 @@ Machining::ToolPreview( int nEntId, int nFlag) const Frame3d frHead ; m_pGeomDB->GetGroupGlobFrame( nId, frHead) ; Frame3d frRef ; - if ( vtAux.IsSmall()) + if ( vtAux.IsSmall() || AreSameOrOppositeVectorApprox( vtAux, vtDir)) frRef.Set( ptOrig, vtDir) ; else frRef.Set( ptOrig, vtDir, vtAux) ; Frame3d frShow ; - if ( vtBAux.IsSmall()) + if ( vtBAux.IsSmall() || AreSameOrOppositeVectorApprox( vtBAux, vtTool)) frShow.Set( ptEnd + vtTool * GetToolData().m_dLen, vtTool) ; else frShow.Set( ptEnd + vtTool * GetToolData().m_dLen, vtTool, vtBAux) ; diff --git a/Milling.cpp b/Milling.cpp index 76171a3..a03406a 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) ; @@ -2519,7 +2569,7 @@ Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTo bOk = false ; } // aggiungo opportuna retrazione - if ( ! AddSawBladeSideRetract( ptP1, vtRetr, dSafeZ, dSawEndElev, dAppr)) { + if ( ! AddSawBladeSideRetract( ptP1, vtRetr, vtTool, dSafeZ, dSawEndElev, dAppr)) { m_pMchMgr->SetLastError( 2312, "Error in Milling : Retract not computable") ; return false ; } @@ -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,141 @@ 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) + // considero come elevazione lo step dalla passata precedente + dStElev = dStep ; + // 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 +2790,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 +2852,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 +2863,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, vtTool, 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 +2935,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 +3072,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 +3115,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 +3163,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 +3294,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, vtTool, 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 +3466,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 +3575,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 +3644,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 +3759,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 +4008,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 +4111,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 +4128,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()) ; @@ -3871,7 +4196,8 @@ Milling::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, //---------------------------------------------------------------------------- bool -Milling::AddSawBladeSideRetract( const Point3d& ptP, const Vector3d& vtRetr, double dSafeZ, double dEndElev, double dAppr) +Milling::AddSawBladeSideRetract( const Point3d& ptP, const Vector3d& vtRetr, const Vector3d& vtTool, + double dSafeZ, double dEndElev, double dAppr) { // per retrazione orizzontale vtAppr deve essere già stato sistemato dal chiamante // se sopra uscita c'è spazio per sicurezza o approccio @@ -3892,7 +4218,16 @@ Milling::AddSawBladeSideRetract( const Point3d& ptP, const Vector3d& vtRetr, dou return false ; } // 4b -> movimento di risalita sopra il punto finale - Point3d ptP4b = ptP4a + vtRetr * ( dSafeZ - dAppr) ; + Vector3d vtMove = vtRetr ; + double dMove = dSafeZ - dAppr ; + if ( ! m_bTiltingTab && vtRetr.z < sin( -ANG_RIGHT / 2)) { + vtMove = Vector3d( vtTool.x, vtTool.y, 0) ; + if ( vtMove.Normalize()) + dMove = dSafeZ ; + else + vtMove = vtRetr ; + } + Point3d ptP4b = ptP4a + vtMove * dMove ; if ( AddRapidMove( ptP4b) == GDB_ID_NULL) return false ; } @@ -5396,7 +5731,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 +5767,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..686c233 100644 --- a/Milling.h +++ b/Milling.h @@ -102,7 +102,8 @@ class Milling : public Machining bool AddDirectApproach( const Point3d& ptP) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ, double dElev, double dAppr, bool bAboveEnd) ; - bool AddSawBladeSideRetract( const Point3d& ptP, const Vector3d& vtRetr, double dSafeZ, double dEndElev, double dAppr) ; + bool AddSawBladeSideRetract( const Point3d& ptP, const Vector3d& vtRetr, const Vector3d& vtTool, + double dSafeZ, double dEndElev, double dAppr) ; bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtTool, double dStElev, bool bInvert, const ICurveComposite* pCompo, Point3d& ptP1) const ; bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, @@ -145,7 +146,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 +168,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 3100b77..b43de94 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -170,13 +170,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 ; @@ -240,11 +259,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) ; } } } @@ -363,32 +384,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 ; @@ -445,6 +517,66 @@ Operation::GetPointUnderRaw( const Point3d& ptP, const Vector3d& vtTool, double return false ; } +//---------------------------------------------------------------------------- +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 @@ -950,8 +1082,9 @@ Operation::ApproxWithArcsIfUseful( ICurveComposite* pCompo, bool bCareTempProp) // limito l'approssimazione alle curve piane Frame3d frRef ; frRef.Set( ORIG, vtExtr) ; + Frame3d frInvRef = frRef ; frInvRef.Invert() ; BBox3d b3Crv ; - if ( ! pCompo->GetBBox( frRef, b3Crv) || abs( b3Crv.GetMax().z - b3Crv.GetMin().z - dThick) > 100 * EPS_SMALL) + if ( ! pCompo->GetBBox( frInvRef, b3Crv) || abs( b3Crv.GetMax().z - b3Crv.GetMin().z - dThick) > 100 * EPS_SMALL) return true ; // porto la curva nel suo piano perchè ApproxWithArcsEx funziona bene solo nel piano XY (all'uscita va ripristinato il rif. originale) pCompo->ToLoc( frRef) ; @@ -1014,7 +1147,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à @@ -1499,8 +1632,17 @@ Operation::CalculateAxesValues( const string& sHint, bool bRotContOnNext, bool b if ( m_pMchMgr->GetCurrMachine()->GetCurrAxisToken( nLinAxes + i, sAxToken) && szKey == Trim( sAxToken)) { double dVal ; - if ( FromString( szVal, dVal)) + if ( FromString( szVal, dVal)) { + double dOffset = 0 ; + m_pMchMgr->GetCurrMachine()->GetCurrAxisOffset( nLinAxes + i, dOffset) ; + if ( abs( dOffset) > EPS_ANG_SMALL) + dVal -= dOffset ; + bool bInvert = false ; + m_pMchMgr->GetCurrMachine()->GetCurrAxisInvert( nLinAxes + i, bInvert) ; + if ( bInvert) + dVal = -dVal ; vAxRotPrec[i] = dVal ; + } break ; } } @@ -2814,7 +2956,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) ; @@ -2836,12 +2978,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) ; } } @@ -2866,14 +3008,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 b6e9142..25a2efc 100644 --- a/Operation.h +++ b/Operation.h @@ -71,14 +71,22 @@ 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, const Vector3d& vtDir, double& dElev) const ; bool GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad, const Vector3d& vtDir, double& dElev) const ; - bool GetPointUnderRaw( const Point3d& ptP, const Vector3d& vtTool, double dToolRad, double dToolRadForElev, - double dToolLen, bool bIsSaw, double dSafeZ, const Vector3d& vtDir, double& dElev) const ; + bool GetElevation( int nPhase, const Point3d& ptP, const Vector3d& vtTool, double dRad, double dLen, + const Vector3d& vtDir, double& dElev) const ; + bool 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 ; @@ -130,7 +138,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 d1d14a0..3f76a8d 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -116,9 +116,11 @@ 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 ; + pPock->m_dOpenMinSafe = m_dOpenMinSafe ; } catch( ...) { delete pPock ; @@ -244,6 +246,7 @@ Pocketing::Pocketing( void) m_bAboveHead = true ; m_bAggrBottom = false ; m_bOpenOutRaw = false ; + m_dOpenMinSafe = 0 ; } //---------------------------------------------------------------------------- @@ -920,11 +923,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 (" + @@ -1614,7 +1637,7 @@ Pocketing::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) ; @@ -1629,6 +1652,9 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) int nOpenOutRaw ; m_bOpenOutRaw = ( FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenOutRaw="), nOpenOutRaw) && nOpenOutRaw != 0) ; + // recupero eventuale minima lunghezza di attacco su lato aperto + FromString( ExtractInfo( m_Params.m_sUserNotes, "OpenMinSafe="), m_dOpenMinSafe) ; + // se richiesta anteprima if ( nPvId != GDB_ID_NULL) { // creo gruppo per geometria di lavorazione del percorso @@ -1747,7 +1773,6 @@ Pocketing::CalcRegionElevation( const ICurveComposite* pCompo, const Vector3d& v int nYStep = max( int( ceil( ( dDimY - 20 * EPS_SMALL) / STEP)), 2) ; double dYStep = ( nYStep > 0 ? ( dDimY - 20 * EPS_SMALL) / nYStep : 0) ; // calcolo le linee di svuotatura - int nCount = 0 ; for ( int i = 1 ; i < nYStep ; ++ i) { // definisco la linea PtrOwner pLine( CreateCurveLine()) ; @@ -1833,7 +1858,8 @@ Pocketing::VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& // 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, 0, m_AggrBottom.vtMDir, MCH_AGB_DELTAMAX_MDIR, dCurrDist, vtCurrDir)) { + GetMinDistanceFromRawSide( m_nPhase, ptP, 0, 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 @@ -1984,13 +2010,13 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con if ( ! GetElevation( m_nPhase, ptStart, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElev) || dTestElev < EPS_SMALL) bOutRawLeadIn = true ; // sistemo attacco (per essere completamente fuori dal grezzo) - if ( bOutRawLeadIn || m_bOpenOutRaw) + if ( bOutRawLeadIn || m_bOpenOutRaw) vpCrvs[0]->ExtendStartByLen( m_TParams.m_dDiam / 2 + dSafeZ) ; } // se non ottimizzato e utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore - if ( ( ! bOptimizedZigZag || ! ( bOutRawLeadIn || m_bOpenOutRaw)) && m_TParams.m_nType == TT_MILL_NOTIP) { - if ( ! LeadInIsOk()) { + if ( ( ! bOptimizedZigZag || ! ( bOutRawLeadIn || m_bOpenOutRaw)) && m_TParams.m_nType == TT_MILL_NOTIP) { + if ( ! LeadInRawIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } @@ -2091,13 +2117,17 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con double dStElev ; GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev) ; dStElev = max( dStElev, j * dStep) ; - bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bUnderRaw) + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bAhUnderRaw || bUhAboveRaw) dStElev = max( dStElev, j * dStep) ; dStElev -= ( ptP1 - ptStart) * vtExtr ; // se ottimizzata e attacco nel grezzo - if ( bOptimizedZigZag && ! ( bOutRawLeadIn || m_bOpenOutRaw)) { + if ( bOptimizedZigZag && ! ( bOutRawLeadIn || m_bOpenOutRaw)) { // se richiesto attacco a zigzag o a spirale, l'elevazione va nell'attacco if ( GetLeadInType() == POCKET_LI_ZIGZAG || GetLeadInType() == POCKET_LI_HELIX) { ptP1 += vtExtr * dStElev ; @@ -2157,11 +2187,10 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con double dEndElev = dElev ; Point3d ptP1 ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev, true)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, true, ptP1, dEndElev)) { m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } - dEndElev = max( dEndElev, j * dStep) ; // se lucidatura o caso ottimizzato e ultimo percorso di ultimo step, aggiungo retrazione if ( ( m_TParams.m_nType == TT_MILL_POLISHING || bOptimizedZigZag) && k == nPath - 1 && j == nStep) { if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { @@ -2239,11 +2268,16 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con return false ; // determino elevazione su inizio attacco double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, + GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dStep ; - bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bUnderRaw) + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bAhUnderRaw || bUhAboveRaw) dStElev = max( dStElev, dStep) ; dStElev -= ( ptP1 - ptStart) * vtExtr ; // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco @@ -2306,7 +2340,7 @@ Pocketing::AddZigZag( const ICurveComposite* pCompo, const Vector3d& vtTool, con // aggiungo uscita double dEndElev = dElev ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, false, ptP1, dEndElev)) { m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } @@ -2998,7 +3032,7 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con // se utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP) { - if ( ! LeadInIsOk()) { + if ( ! LeadInRawIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } @@ -3071,9 +3105,13 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con double dStElev ; if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dStep ; - bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bUnderRaw) + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bAhUnderRaw || bUhAboveRaw) dStElev = max( dStElev, dStep) ; dStElev -= ( ptP1 - ptStart) * vtExtr ; // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco @@ -3137,7 +3175,7 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con Point3d ptP1 ; double dEndElev = dElev ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, ptP1, dEndElev)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, nullptr, bSplitArcs, false, ptP1, dEndElev)) { m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } @@ -3225,9 +3263,13 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con double dStElev ; if ( ! GetElevation( m_nPhase, ptS - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = j * dStep ; - bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetPointUnderRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bUnderRaw) + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bAhUnderRaw || bUhAboveRaw) dStElev = max( dStElev, j * dStep) ; dStElev -= ( ptP - ptS) * vtExtr ; // sempre approccio di collegamento @@ -3253,7 +3295,7 @@ Pocketing::AddOneWay( const ICurveComposite* pCompo, const Vector3d& vtTool, con Point3d ptQ ; double dEndElev = dElev ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptE, frPocket.VersX(), vtExtr, nullptr, bSplitArcs, ptQ, dEndElev, true)) { + if ( ! AddLeadOut( ptE, frPocket.VersX(), vtExtr, nullptr, bSplitArcs, true, ptQ, dEndElev)) { m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } @@ -3339,7 +3381,7 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c bool bOutStart = ( nReg == 1 && bMidOpen) ; if ( bOutStart && ! bOptimizedTrap) { // calcolo il punto fuori - Point3d ptOut = ptMidOpen + vtMidOut * ( 0.5 * m_TParams.m_dDiam + dSafeZ) ; + Point3d ptOut = ptMidOpen + vtMidOut * ( 0.5 * m_TParams.m_dDiam + max( dSafeZ, m_dOpenMinSafe)) ; // verifico che il punto sia veramente fuori dal grezzo double dStElev ; bOutStart = ( ! GetElevation( m_nPhase, ptOut, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dStElev) || dStElev < EPS_SMALL) ; @@ -3367,7 +3409,7 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart && ! bForcedOutStart) { - if ( ! LeadInIsOk()) { + if ( ! LeadInRawIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } @@ -3413,9 +3455,13 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c double dStElev ; if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dStep ; - bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bUnderRaw || ( bOutStart && ! m_bAboveHead)) + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bAhUnderRaw || bUhAboveRaw) dStElev = max( dStElev, dStep) ; dStElev -= ( ptP1 - ptStart) * vtExtr ; // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco @@ -3503,12 +3549,10 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c Point3d ptP1 ; double dEndElev = dElev ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, ptP1, dEndElev)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptP1, dEndElev)) { m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } - if ( ! m_bAboveHead) - dEndElev = max( dEndElev, j * dStep) ; // aggiungo retrazione if ( ! AddRetract( ptP1, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; @@ -3585,7 +3629,7 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) { - if ( ! LeadInIsOk()) { + if ( ! LeadInRawIsOk()) { m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; return false ; } @@ -3639,9 +3683,13 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, double dStElev ; if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) dStElev = dStep ; - bool bUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && - GetPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; - if ( bUnderRaw || ( bOutStart && ! m_bAboveHead)) + bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab && + GetAhPointUnderRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + bool bUhAboveRaw = ! m_bAboveHead && + GetUhPointAboveRaw( ptP1, vtTool, 0, GetRadiusForStartEndElevation(), + m_TParams.m_dLen, false, dSafeZ, vtTool, dStElev) ; + if ( bAhUnderRaw || bUhAboveRaw) dStElev = max( dStElev, dStep) ; dStElev -= ( ptP1 - ptStart) * vtExtr ; // se attacco a zigzag o a spirale o a scivolo, l'elevazione va nell'attacco @@ -3729,12 +3777,10 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, Point3d ptQ ; double dEndElev = dElev ; SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, ptQ, dEndElev)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, pRCrv, bSplitArcs, false, ptQ, dEndElev)) { m_pMchMgr->SetLastError( 2416, "Error in Pocketing : LeadOut not computable") ; return false ; } - if ( ! m_bAboveHead) - dEndElev = max( dEndElev, j * dStep) ; // aggiungo retrazione if ( ! AddRetract( ptQ, vtTool, dSafeZ, dSafeAggrBottZ, dEndElev, dAppr)) { m_pMchMgr->SetLastError( 2417, "Error in Pocketing : Retract not computable") ; @@ -3844,7 +3890,7 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, // recupero la prossima curva di offset PtrOwner pNextOffs ; if ( ! vCrvStack.empty()) { - pNextOffs.Set( Release( vCrvStack.back())) ; + pNextOffs.Set( vCrvStack.back()) ; vCrvStack.pop_back() ; dCurrRad = vRadStack.back() ; vRadStack.pop_back() ; @@ -3861,7 +3907,7 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, if ( bNextOk) { // sistemo per prossimo step dCurrRad = dRad ; - pOffs.Set( Release( pNextOffs)) ; + pOffs.Set( pNextOffs) ; // nuovo valore pari allo step dOffs = GetSideStep() ; } @@ -3888,7 +3934,7 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, // calcolo il collegamento (garantendo che non esca dalla svuotatura) PtrOwner pCrvLink( CreateCurveComposite()) ; if ( CalcBoundedLink( ptStart, ptEnd, vOffs[0], pCrvLink)) - vLinks[i].Set( Release( pCrvLink)) ; + vLinks[i].Set( pCrvLink) ; else { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; @@ -4516,14 +4562,22 @@ Pocketing::AdjustTrapezoidSpiralForAngles( ICurveComposite* pMCrv, const ICurveC } } - // se il lato opposto a quello di riferimento è chiuso ha senso aggiungere solo se il punto è sotto la linea di svuotatura + // se il lato opposto a quello di riferimento è chiuso bisogna distinguere i casi else { if ( ptP2.y < dYCoord) { pCompo->AddPoint( ptP2) ; - Point3d ptCrv ; - pMCrv->GetStartPoint( ptCrv) ; - pCompo->AddLine( ptCrv) ; } + else { + Vector3d vtDir ; + pLine->GetStartDir( vtDir) ; + if ( bStart) + vtDir.Invert() ; + Point3d ptP2N = ptP2 - m_TParams.m_dDiam / 2 * abs( vtDir.x / vtDir.y) * vtDir ; + pCompo->AddPoint( ptP2N) ; + } + Point3d ptCrv ; + pMCrv->GetStartPoint( ptCrv) ; + pCompo->AddLine( ptCrv) ; } // setto temp prop per ricordare che è curva aggiuntiva per pulire angoli @@ -4686,7 +4740,7 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V // se forzato come fuori dal grezzo if ( m_bOpenOutRaw) { - Point3d ptNewStart = ptP + vtDirP * ( m_TParams.m_dDiam / 2 + dSafeZ) ; + Point3d ptNewStart = ptP + vtDirP * ( m_TParams.m_dDiam / 2 + max( dSafeZ, m_dOpenMinSafe)) ; pCompo->AddLine( ptNewStart, ! bLeadIn) ; bIsOutsideRaw = true ; return true ; @@ -4697,14 +4751,19 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V Vector3d vtNorm ; if ( ! CalcDistanceFromRawSurface( m_nPhase, ptP, vtDirP, dDist, vtNorm)) return false ; + if ( abs( dDist) < EPS_SMALL) { + ptP -= vtDirP ; + if ( ! CalcDistanceFromRawSurface( m_nPhase, ptP, vtDirP, dDist, vtNorm)) + return false ; + } - // calcolo eventuali fattori correttivi + // calcolo eventuali fattori correttivi (se uscita approx. con fianco utensile) double dCorr = 1 ; double dDistRef = dDist ; double dDistMin ; Vector3d vtNormMin ; - if ( CalcDistanceFromRawSurface( m_nPhase, ptP, vtNorm, dDistMin, vtNormMin)) { - if ( abs( dDistMin) < abs( dDist) && abs( dDistMin) > EPS_SMALL) { + if ( abs( vtTool * vtNorm) < 0.5 && CalcDistanceFromRawSurface( m_nPhase, ptP, vtNorm, dDistMin, vtNormMin)) { + if ( abs( dDistMin) < abs( dDist) && abs( dDistMin) > EPS_SMALL) { dDistRef = dDistMin ; dCorr = dDist / dDistMin ; } @@ -4712,12 +4771,12 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V // se vicino al bordo del grezzo if ( dDistRef < m_TParams.m_dDiam / 2 + EPS_SMALL) { - Point3d ptTest = ptP + vtDirP * ( dDist + ( m_TParams.m_dDiam / 2 + dSafeZ) * dCorr) ; + Point3d ptTest = ptP + vtDirP * ( dDist + ( m_TParams.m_dDiam / 2 + max( dSafeZ, m_dOpenMinSafe)) * dCorr) ; ptTest += - vtTool * dDepth ; double dTestElev ; // se è fuori dal grezzo if ( ! GetElevation( m_nPhase, ptTest, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElev) || dTestElev < EPS_SMALL) { - Point3d ptNewStart = ptP + vtDirP * ( dDist + ( m_TParams.m_dDiam / 2 + dSafeZ) * dCorr) ; + Point3d ptNewStart = ptP + vtDirP * ( dDist + ( m_TParams.m_dDiam / 2 + max( dSafeZ, m_dOpenMinSafe)) * dCorr) ; pCompo->AddLine( ptNewStart, ! bLeadIn) ; bIsOutsideRaw = true ; } @@ -4737,12 +4796,12 @@ Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite* pCompo, const V // se vicino al bordo del grezzo if ( dDist < m_TParams.m_dDiam / 2 + EPS_SMALL) { - Point3d ptTestO = ptP + vtDirO * ( dDist + m_TParams.m_dDiam / 2 + dSafeZ) ; + Point3d ptTestO = ptP + vtDirO * ( dDist + m_TParams.m_dDiam / 2 + max( dSafeZ, m_dOpenMinSafe)) ; ptTestO += - vtTool * dDepth ; double dTestElevO ; // se è fuori dal grezzo uso inizio ruotato if ( ! GetElevation( m_nPhase, ptTestO, vtTool, m_TParams.m_dDiam / 2, vtTool, dTestElevO) || dTestElevO < EPS_SMALL) { - Point3d ptNewStart = ptP + vtDirO * ( dDist + m_TParams.m_dDiam / 2 + dSafeZ) ; + Point3d ptNewStart = ptP + vtDirO * ( dDist + m_TParams.m_dDiam / 2 + max( dSafeZ, m_dOpenMinSafe)) ; pCompo->AddLine( ptNewStart, ! bLeadIn) ; bIsOutsideRaw = true ; } @@ -4810,7 +4869,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") ; @@ -5137,8 +5196,6 @@ Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, con int nType = GetLeadInType() ; if ( nType == POCKET_LI_GLIDE && ( pRCrv == nullptr || pRCrv->GetCurveCount() == 0)) nType = POCKET_LI_NONE ; - // senso di rotazione da dir tg a dir esterna - bool bCcwRot = true ; // Calcolo punto iniziale switch ( nType) { case POCKET_LI_NONE : @@ -5225,8 +5282,11 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 return ( AddLinearMove( ptStart, MCH_CL_LEADIN) != GDB_ID_NULL) ; } // altrimenti diretto - else + else { nType = POCKET_LI_NONE ; + if ( m_TParams.m_nType == TT_MILL_NOTIP) + return false ; + } } // Se a scivolo e fattibile if ( nType == POCKET_LI_GLIDE) { @@ -5280,7 +5340,18 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 //---------------------------------------------------------------------------- bool Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - const ICurveComposite* pRCrv, bool bSplitArcs, Point3d& ptP1, double& dElev, bool bNoneForced) + const ICurveComposite* pRCrv, bool bSplitArcs, bool bNoneForced, + Point3d& ptP1, double& dElev) +{ + bool bOppositeHome ; + return AddLeadOut( ptEnd, vtEnd, vtN, pRCrv, bSplitArcs, bNoneForced, ptP1, dElev, bOppositeHome) ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, + const ICurveComposite* pRCrv, bool bSplitArcs, bool bNoneForced, + Point3d& ptP1, double& dElev, bool& bOppositeHome) { // assegno i parametri int nType = GetLeadOutType() ; @@ -5299,8 +5370,13 @@ Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector dElev = dEndElev ; // 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 : @@ -5335,11 +5411,17 @@ Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector dElev = dEndElev ; // 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 ; } @@ -5349,8 +5431,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) ; } //---------------------------------------------------------------------------- @@ -5459,25 +5542,49 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) AdjustContourStart( pCompo) ; // raggio di riferimento per offset double dRad = 0.5 * m_TParams.m_dDiam + GetOffsR() ; - // estraggo tutte le curve in un vettore + // estraggo parti con proprietà uniforme in un vettore ICURVEPOVECTOR vpCrvs ; - vpCrvs.reserve( pCompo->GetCurveCount()) ; - while ( pCompo->GetCurveCount() > 0) - vpCrvs.emplace_back( pCompo->RemoveFirstOrLastCurve( false)) ; - // elimino le curve troppo corte (10 epsilon) - for ( int i = 0 ; i < int( vpCrvs.size()) ;) { - double dLen = 0 ; vpCrvs[i]->GetLength( dLen) ; - if ( dLen < 10 * EPS_SMALL) - vpCrvs.erase( vpCrvs.begin() + i) ; - else - ++ i ; + int nCurrTempProp ; + int nParStart = 0 ; + for ( int i = 0 ; i < pCompo->GetCurveCount() ; ++ i) { + int nTempProp ; + pCompo->GetCurveTempProp( i, nTempProp) ; + if ( i == 0) { + nCurrTempProp = nTempProp ; + nParStart = i ; + } + else if ( nCurrTempProp != nTempProp) { + PtrOwner pCrv( pCompo->CopyParamRange( nParStart, i)) ; + if ( IsNull( pCrv)) + return false ; + pCrv->SetTempProp( nCurrTempProp) ; + pCrv->SetExtrusion( vtExtr) ; + vpCrvs.emplace_back( Release( pCrv)) ; + nCurrTempProp = nTempProp ; + nParStart = i ; + } } + PtrOwner pCrv( pCompo->CopyParamRange( nParStart, pCompo->GetCurveCount())) ; + if ( IsNull( pCrv)) + return false ; + pCrv->SetTempProp( nCurrTempProp) ; + pCrv->SetExtrusion( vtExtr) ; + vpCrvs.emplace_back( Release( pCrv)) ; // offsetto del raggio le curve aperte for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { - if ( vpCrvs[i]->GetTempProp() == 1) - vpCrvs[i]->SimpleOffset( dRad) ; + if ( vpCrvs[i]->GetTempProp() == 1) { + OffsetCurve OffsCrv ; + if ( ! OffsCrv.Make( vpCrvs[i], dRad, ICurve::OFF_FILLET) || OffsCrv.GetCurveCount() == 0) { + m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ; + return false ; + } + vpCrvs[i].Set( OffsCrv.GetLongerCurve()) ; + vpCrvs[i]->SetTempProp( 1) ; + } } // reinserisco le curve, chiudendo eventuali gap + pCompo->Clear() ; + pCompo->SetExtrusion( vtExtr) ; bool bOpenCurr = false ; double dDiam = 1.05 * m_TParams.m_dDiam + 2 * GetOffsR() ; for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { @@ -5510,8 +5617,18 @@ Pocketing::AdjustContourWithOpenEdges( ICurveComposite* pCompo) pJCrv->ToGlob( frPocket) ; vpCrvs[i]->ToGlob( frPocket) ; // taglio opportunamente le curve + bool bFound = false ; IntCrvCrvInfo aInfo ; - if ( intCC.GetIntCrvCrvInfo( intCC.GetIntersCount() - 1, aInfo)) { + if ( intCC.GetIntersCount() > 0) { + // cerco la prima intersezione che entra nella curva aperta + for ( int j = 0 ; j < intCC.GetIntersCount() ; ++ j) { + if ( intCC.GetIntCrvCrvInfo( j, aInfo) && aInfo.IciA[0].nPrevTy == ICCT_OUT) { + bFound = true ; + break ; + } + } + } + if ( bFound) { pJCrv->TrimEndAtParam( aInfo.IciA[0].dU) ; vpCrvs[i]->TrimStartAtParam( aInfo.IciB[0].dU) ; pCompo->AddCurve( ::Release( pJCrv), true, 10 * EPS_SMALL) ; diff --git a/Pocketing.h b/Pocketing.h index 7afb60c..a096a30 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -129,7 +129,11 @@ class Pocketing : public Machining const ICurveComposite* pCompo, const ICurveComposite* pRCrv, bool bAtLeft, bool bSplitArcs, bool bNoneForced = false, bool bSkipControl = false) ; bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - const ICurveComposite* pRCrv, bool bSplitArcs, Point3d& ptP1, double& dElev, bool bNoneForced = false) ; + const ICurveComposite* pRCrv, bool bSplitArcs, bool bNoneForced, + Point3d& ptP1, double& dElev) ; + bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, + const ICurveComposite* pRCrv, bool bSplitArcs, bool bNoneForced, + Point3d& ptP1, double& dElev, bool& bOppositeHome) ; double GetRadiusForStartEndElevation( void) const ; bool GetMidOfLongestOpenSide( const ICurveComposite* pCompo, Point3d& ptMid, Vector3d& vtMidOut) ; bool AdjustContourWithOpenEdges( ICurveComposite* pCompo) ; @@ -161,7 +165,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) && @@ -182,9 +186,11 @@ 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 AggrBottom m_AggrBottom ; // dati eventuale aggregato da sotto bool m_bOpenOutRaw ; // flag forzatura lati aperti sempre fuori dal grezzo + double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto } ; \ No newline at end of file diff --git a/Processor.cpp b/Processor.cpp index b04a865..914daec 100644 --- a/Processor.cpp +++ b/Processor.cpp @@ -184,8 +184,8 @@ Processor::ProcessDisposition( int nOpId, int nOpInd) bool bEmpty = pDisp->IsEmpty() ; bool bSomeByHand = pDisp->GetSomeByHand() ; - // Se disposizione con movimenti macchina - if ( ! pDisp->IsEmpty()) { + // Se disposizione con movimenti autonomi e utensile associato + if ( ! pDisp->IsEmpty() && pDisp->IsWithTool()) { // Recupero l'utensile della disposizione corrente string sTool ; string sHead ; int nExit ; string sTcPos ; if ( ! pDisp->GetToolData( sTool, sHead, nExit, sTcPos)) 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..3331bb6 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 @@ -1831,10 +1851,10 @@ Sawing::ProcessLine( const ICurve* pCrvP, const ICurveLine* pLineC, const ICurve // Eventuale variazioni di velocità all'inizio e alla fine del percorso FseVar FvVar ; if ( pCrvP == nullptr) { - string sFsta = ExtractInfo( m_Params.m_sUserNotes, "Fsta:") ; + string sFsta = ExtractInfo( m_Params.m_sUserNotes, "Fsta=") ; if ( ! sFsta.empty()) { string sLen, sPu ; - SplitFirst( sFsta, "=", sLen, sPu) ; + SplitFirst( sFsta, ",", sLen, sPu) ; FromString( sLen, FvVar.dLenStart) ; FvVar.dLenStart = max( FvVar.dLenStart, 0.) ; FromString( sPu, FvVar.dPuStart) ; @@ -1842,10 +1862,10 @@ Sawing::ProcessLine( const ICurve* pCrvP, const ICurveLine* pLineC, const ICurve } } if ( pCrvN == nullptr) { - string sFend = ExtractInfo( m_Params.m_sUserNotes, "Fend:") ; + string sFend = ExtractInfo( m_Params.m_sUserNotes, "Fend=") ; if ( ! sFend.empty()) { string sLen, sPu ; - SplitFirst( sFend, "=", sLen, sPu) ; + SplitFirst( sFend, ",", sLen, sPu) ; FromString( sLen, FvVar.dLenEnd) ; FvVar.dLenEnd = max( FvVar.dLenEnd, 0.) ; FromString( sPu, FvVar.dPuEnd) ; @@ -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..dc8c7f8 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 ; @@ -679,11 +687,13 @@ Simulator::FindAndManageOperationStart( bool bStart, bool bFirst, int& nStatus) } // cambio fase m_pMchMgr->SetCurrPhase( nPhase, ( nPhase == 1)) ; - // aggiorno utensile e assi conseguenti - int nErr ; - if ( ! UpdateTool( bFirst, nErr)) { - nStatus = CalcStatusOnError( nErr) ; - return false ; + // se previsto, aggiorno utensile e assi conseguenti + if ( pDisp->IsWithTool()) { + int nErr ; + if ( ! UpdateTool( bFirst, nErr)) { + nStatus = CalcStatusOnError( nErr) ; + return false ; + } } ++ m_nOpInd ; // richiamo gestione evento inizio disposizione @@ -1038,21 +1048,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 +1301,18 @@ 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 (angolo movimento verso la testa oltre 5.8deg), non eseguo asportazione + Vector3d vtDirM = Media( vtHiL, vtHfL) ; + vtDirM.Normalize() ; + double dAxMove = ( ptHfL - ptHiL) * vtDirM ; + if ( dAxMove < -EPS_SMALL) { + double dMove = ( ptHfL - ptHiL).Len() ; + if ( dAxMove < -0.1 * abs( dMove)) + 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