diff --git a/MachiningsMgr.h b/MachiningsMgr.h index 143923a..c540687 100644 --- a/MachiningsMgr.h +++ b/MachiningsMgr.h @@ -69,7 +69,7 @@ class MachiningsMgr double GetExtSawArcMinRad( void) { return m_dExtSawArcMinRad ; } bool SetSplitArcs( int nFlag) ; - double GetSplitArcs( void) + int GetSplitArcs( void) { return m_nSplitArcs ; } private : diff --git a/Milling.cpp b/Milling.cpp index a1cc991..2d8fefe 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -193,6 +193,9 @@ Milling::SetParam( int nType, bool bVal) case MPA_INVERT : m_Params.m_bInvert = bVal ; return true ; + case MPA_LEAVETAB : + m_Params.m_bLeaveTab = bVal ; + return true ; } return false ; } @@ -472,6 +475,14 @@ Milling::Apply( bool bRecalc) bool Milling::GetParam( int nType, bool& bVal) const { + switch ( nType) { + case MPA_INVERT : + bVal = m_Params.m_bInvert ; + return true ; + case MPA_LEAVETAB : + bVal = m_Params.m_bLeaveTab ; + return true ; + } return false ; } @@ -897,7 +908,7 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) double dOffs = 0.5 * m_TParams.m_dTDiam + GetOffsR() ; if ( m_Params.m_nWorkSide != MILL_WS_CENTER && abs( dOffs) > EPS_SMALL) { double dSignOffs = ( m_Params.m_nWorkSide == MILL_WS_RIGHT) ? dOffs : - dOffs ; - if ( ! pCompo->SimpleOffset( dSignOffs, ICurve::OFF_EXTEND)){ + if ( ! pCompo->SimpleOffset( dSignOffs, ICurve::OFF_EXTEND)) { LOG_INFO( GetEMkLogger(), "Error in Milling : SimpleOffset not computable") ; return false ; } @@ -943,9 +954,11 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) string sPathName ; m_pGeomDB->GetName( nPathId, sPathName) ; - // eventuale approssimazione con segmenti di linea - - bool bSplitArcs = ( m_pMchMgr->GetCurrMachiningsMgr()->GetSplitArcs() == SPLAR_ALWAYS) ; + // eventuale approssimazione con segmenti di retta + int nSplitArcs = m_pMchMgr->GetCurrMachiningsMgr()->GetSplitArcs() ; + bool bSplitArcs = ( nSplitArcs == SPLAR_ALWAYS || + ( nSplitArcs == SPLAR_NO_XY_PLANE && ! vtExtr.IsZplus()) || + ( nSplitArcs == SPLAR_GEN_PLANE && vtExtr.IsGeneric())) ; if ( bSplitArcs) { const double ANG_TOL_MAX_DEG = 90 ; PolyLine PL ; @@ -984,6 +997,18 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) if ( ! vtExtr.IsSmall()) vtTool = vtExtr ; + // calcolo l'elevazione massima + double dElev ; + if ( CalcElevation( pCompo, vtTool, dDepth, dElev)) { + if ( dElev < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) { + BBox3d b3Crv ; + pCompo->GetLocalBBox( b3Crv) ; + dElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z) ; + } + } + else + return false ; + // assegno il vettore estrazione al gruppo del percorso m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; // assegno il punto di inizio al gruppo del percorso @@ -992,6 +1017,68 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) // Imposto dati comuni SetPathId( nPxId) ; SetToolDir( vtTool) ; + + // Se una sola passata + if ( m_Params.m_dStep < EPS_SMALL || dElev <= m_Params.m_dStep) { + if ( ! AddStandardMilling( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) + return false ; + } + // se altrimenti passate a zig-zag + else if ( m_Params.m_nStepType == MILL_ST_ZIGZAG) { + if ( ! AddZigZagMilling( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) + return false ; + } + // se altrimenti passate a one-way + else if ( m_Params.m_nStepType == MILL_ST_ONEWAY) { + if ( ! AddOneWayMilling( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) + return false ; + } + // se altrimenti passate a spirale + else if ( m_Params.m_nStepType == MILL_ST_SPIRAL) { + if ( ! AddSpiralMilling( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) + return false ; + } + + // incremento numero di fresate + ++ m_nMills ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Milling::CalcElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, + double& dElev) +{ + dElev = 0 ; + int nMaxInd = pCompo->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pCompo->GetCurve( i) ; + // calcolo elevazione + double dCurrElev ; + Point3d ptStart, ptMid, ptEnd ; + pCrvC->GetStartPoint( ptStart) ; + pCrvC->GetMidPoint( ptMid) ; + pCrvC->GetEndPoint( ptEnd) ; + Vector3d vtDepth = vtTool * dDepth ; + if ( GetElevation( m_nPhase, ptStart - vtDepth, ptMid - vtDepth, ptEnd - vtDepth, vtTool, dCurrElev)) { + if ( dCurrElev > dElev) + dElev = dCurrElev ; + } + else { + LOG_INFO( GetEMkLogger(), "Error in Milling : Entity GetElevation") ; + return false ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Milling::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) +{ // recupero distanza di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; // lunghezza di approccio/retrazione @@ -999,7 +1086,7 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) // ciclo sulle curve elementari bool bClosed = pCompo->IsClosed() ; - nMaxInd = pCompo->GetCurveCount() - 1 ; + int nMaxInd = pCompo->GetCurveCount() - 1 ; for ( int i = 0 ; i <= nMaxInd ; ++ i) { // curva corrente const ICurve* pCrvC = pCompo->GetCurve( i) ; @@ -1009,21 +1096,6 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) return false ; // aggiungo affondamento pCurve->Translate( - vtTool * dDepth) ; - // calcolo elevazione - double dElev ; - Point3d ptStart, ptMid, ptEnd ; - pCurve->GetStartPoint( ptStart) ; - pCurve->GetMidPoint( ptMid) ; - pCurve->GetEndPoint( ptEnd) ; - if ( ! GetElevation( m_nPhase, ptStart, ptMid, ptEnd, vtTool, dElev)) { - LOG_INFO( GetEMkLogger(), "Error in Milling : Entity GetElevation") ; - return false ; - } - if ( dElev < EPS_SMALL && AreSameVectorApprox( vtExtr, Z_AX)) { - BBox3d b3Crv ; - pCurve->GetLocalBBox( b3Crv) ; - dElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z) ; - } // se prima entità, approccio e affondo if ( i == 0) { // dati inizio entità @@ -1033,7 +1105,7 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) pCurve->GetStartDir( vtStart) ; // determino inizio attacco Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, ptP1)) + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, false, ptP1)) return false ; // aggiungo approccio per frese normali if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { @@ -1057,7 +1129,7 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) } // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, false, bSplitArcs)) { LOG_INFO( GetEMkLogger(), "Error in Milling : LeadIn not computable") ; return false ; } @@ -1091,7 +1163,7 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) // aggiungo uscita Point3d ptP1 ; SetFeed( GetStartFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, ptP1, bSplitArcs)) { + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, false, bSplitArcs, ptP1)) { LOG_INFO( GetEMkLogger(), "Error in Milling : LeadOut not computable") ; return false ; } @@ -1107,10 +1179,494 @@ Milling::ProcessPath( int nPathId, int nPvId, int nClId) // per lame non è necessario } } + return true ; +} - // incremento numero di fresate - ++ m_nMills ; +//---------------------------------------------------------------------------- +bool +Milling::AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) +{ + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + // determino numero e affondamento degli step + int nStep = max( 1, static_cast( ceil( dElev / m_Params.m_dStep))) ; + double dStep = dElev / nStep ; + + bool bClosed = pCompo->IsClosed() ; + int nMaxInd = pCompo->GetCurveCount() - 1 ; + + // ciclo sugli step + for ( int j = 1 ; j <= nStep ; ++ j) { + // ciclo sulle curve elementari + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // flag direzione + bool bInvert = ( ( j % 2) == 0) ; + // curva corrente + const ICurve* pCrvC = pCompo->GetCurve( ( bInvert ? nMaxInd - i : i)) ; + // copio la curva + PtrOwner pCurve( ::GetCurve( pCrvC->Clone())) ; + if ( IsNull( pCurve)) + return false ; + if ( bInvert) + pCurve->Invert() ; + // aggiungo affondamento + pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se prima entità, se primo step approccio e sempre affondo + if ( i == 0) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, bInvert, ptP1)) + return false ; + // se primo step aggiungo approccio per frese normali + if ( j == 1 && ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, dStElev)) + dStElev = dElev ; + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) + return false ; + // affondo al punto iniziale + SetFlag( 0) ; + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( 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 ( j == 1) { + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + } + else { + if ( AddRapidMove( ptP1) == GDB_ID_NULL) + return false ; + } + } + // altrimenti, affondo in feed di testa + else { + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptP1) == GDB_ID_NULL) + return false ; + } + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bInvert, bSplitArcs)) { + LOG_INFO( GetEMkLogger(), "Error in Milling : LeadIn not computable") ; + return false ; + } + } + // elaborazioni sulla curva corrente + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + SetFeed( GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità, uscita e se ultimo step retrazione + if ( i == nMaxInd) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + SetFeed( GetStartFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, bInvert, bSplitArcs, ptP1)) { + LOG_INFO( GetEMkLogger(), "Error in Milling : LeadOut not computable") ; + return false ; + } + // se ultimo step aggiungo retrazione per frese normali + if ( j == nStep && ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, dEndElev)) + dEndElev = dElev ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) + return false ; + } + // per lame non è necessario + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Milling::AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) +{ + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + + // determino numero e affondamento degli step + int nStep = max( 1, static_cast( ceil( dElev / m_Params.m_dStep))) ; + double dStep = dElev / nStep ; + + bool bClosed = pCompo->IsClosed() ; + int nMaxInd = pCompo->GetCurveCount() - 1 ; + + // ciclo sugli step + for ( int j = 1 ; j <= nStep ; ++ j) { + // ciclo sulle curve elementari + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pCompo->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( ::GetCurve( pCrvC->Clone())) ; + if ( IsNull( pCurve)) + return false ; + // aggiungo affondamento + pCurve->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // se prima entità, approccio e affondo + if ( i == 0) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, false, ptP1)) + return false ; + // aggiungo approccio per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, dStElev)) + dStElev = dElev ; + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) + return false ; + // affondo al punto iniziale + SetFlag( 0) ; + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptP1) == GDB_ID_NULL) + return false ; + } + // altrimenti, approccio per lame + else { + // affondo al punto iniziale + SetFlag( 0) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, false, bSplitArcs)) { + LOG_INFO( GetEMkLogger(), "Error in Milling : LeadIn not computable") ; + return false ; + } + } + // elaborazioni sulla curva corrente + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + SetFeed( GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità, uscita e retrazione + if ( i == nMaxInd) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + SetFeed( GetStartFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, false, bSplitArcs, ptP1)) { + LOG_INFO( GetEMkLogger(), "Error in Milling : LeadOut not computable") ; + return false ; + } + // aggiungo retrazione per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, dEndElev)) + dEndElev = dElev ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) + return false ; + } + // per lame non è necessario + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Milling::AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) +{ + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + + // determino numero e affondamento degli step + int nStep = max( 1, static_cast( ceil( dElev / m_Params.m_dStep))) ; + double dStep = dElev / nStep ; + + // determino dati del percorso + double dTotLen ; pCompo->GetLength( dTotLen) ; + bool bClosed = pCompo->IsClosed() ; + int nMaxInd = pCompo->GetCurveCount() - 1 ; + + // se chiuso -> sempre in avanti + if ( bClosed) { + // ciclo sugli step + for ( int j = 0 ; j <= nStep ; ++ j) { + // ciclo sulle curve elementari + double dCurrLen = 0 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pCompo->GetCurve( i) ; + // affondamento a inizio curva + Vector3d vtStaDepth = vtTool * ( dDepth - dElev + min((( j + dCurrLen / dTotLen) * dStep), dElev)) ; + // affondamento a fine curva + double dCrvLen ; pCrvC->GetLength( dCrvLen) ; + dCurrLen += dCrvLen ; + Vector3d vtEndDepth = vtTool * ( dDepth - dElev + min((( j + dCurrLen / dTotLen) * dStep), dElev)) ; + // se prima entità di primo step, approccio e affondo + if ( i == 0 && j == 0) { + // dati inizio entità + Point3d ptStart ; + pCrvC->GetStartPoint( ptStart) ; + ptStart -= vtStaDepth ; + Vector3d vtStart ; + pCrvC->GetStartDir( vtStart) ; + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, false, ptP1)) + return false ; + // aggiungo approccio per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, dStElev)) + dStElev = 0 ; + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) + return false ; + // affondo al punto iniziale + SetFlag( 0) ; + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptP1) == GDB_ID_NULL) + return false ; + } + // altrimenti, affondo al punto iniziale per lame + else { + SetFlag( 0) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, false, bSplitArcs)) { + LOG_INFO( GetEMkLogger(), "Error in Milling : LeadIn not computable") ; + return false ; + } + } + // elaborazioni sulla curva corrente + if ( pCrvC->GetType() == CRV_LINE) { + const ICurveLine* pLine = GetCurveLine( pCrvC) ; + Point3d ptP3 = pLine->GetEnd() ; + ptP3 -= vtEndDepth ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pCrvC->GetType() == CRV_ARC) { + const ICurveArc* pArc = GetCurveArc( pCrvC) ; + Point3d ptCen = pArc->GetCenter() ; + ptCen -= vtStaDepth ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + ptP3 -= vtEndDepth ; + SetFeed( GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità di ultimo step, uscita e retrazione + if ( i == nMaxInd && j == nStep) { + // dati fine entità + Point3d ptEnd ; + pCrvC->GetEndPoint( ptEnd) ; + ptEnd -= vtEndDepth ; + Vector3d vtEnd ; + pCrvC->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + SetFeed( GetStartFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, false, bSplitArcs, ptP1)) { + LOG_INFO( GetEMkLogger(), "Error in Milling : LeadOut not computable") ; + return false ; + } + // aggiungo retrazione per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, dEndElev)) + dEndElev = dElev ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) + return false ; + } + // per lame non è necessario + } + } + } + } + // altrimenti aperto -> avanti e indietro + else { + // ciclo sugli step + for ( int j = 0 ; j <= nStep ; ++ j) { + // ciclo sulle curve elementari + double dCurrLen = 0 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // flag direzione + bool bInvert = ( ( j % 2) == 0) ; + // curva corrente + const ICurve* pCrvC = pCompo->GetCurve( ( bInvert ? nMaxInd - i : i)) ; + // copio la curva + PtrOwner pCurve( ::GetCurve( pCrvC->Clone())) ; + if ( IsNull( pCurve)) + return false ; + if ( bInvert) + pCurve->Invert() ; + // affondamento a inizio curva + Vector3d vtStaDepth = vtTool * ( dDepth - dElev + min((( j + dCurrLen / dTotLen) * dStep), dElev)) ; + // affondamento a fine curva + double dCrvLen ; pCrvC->GetLength( dCrvLen) ; + dCurrLen += dCrvLen ; + Vector3d vtEndDepth = vtTool * ( dDepth - dElev + min((( j + dCurrLen / dTotLen) * dStep), dElev)) ; + // se prima entità di primo step, approccio e affondo + if ( i == 0 && j == 0) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + ptStart -= vtStaDepth ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, bInvert, ptP1)) + return false ; + // aggiungo approccio per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, dStElev)) + dStElev = dElev ; + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) + return false ; + // affondo al punto iniziale + SetFlag( 0) ; + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptP1) == GDB_ID_NULL) + return false ; + } + // altrimenti, affondo per lame + else { + SetFlag( 0) ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bInvert, bSplitArcs)) { + LOG_INFO( GetEMkLogger(), "Error in Milling : LeadIn not computable") ; + return false ; + } + } + // elaborazioni sulla curva corrente + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + ptP3 -= vtEndDepth ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pCurve->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pCurve) ; + Point3d ptCen = pArc->GetCenter() ; + ptCen -= vtStaDepth ; + double dAngCen = pArc->GetAngCenter() ; + Vector3d vtN = pArc->GetNormVersor() ; + Point3d ptP3 ; + pArc->GetEndPoint( ptP3) ; + ptP3 -= vtEndDepth ; + SetFeed( GetFeed()) ; + if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL) + return false ; + } + // se ultima entità di ultimo step, uscita e retrazione + if ( i == nMaxInd && j == nStep) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + ptEnd -= vtEndDepth ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + SetFeed( GetStartFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, bInvert, bSplitArcs, ptP1)) { + LOG_INFO( GetEMkLogger(), "Error in Milling : LeadOut not computable") ; + return false ; + } + // aggiungo retrazione per frese normali + if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, dEndElev)) + dEndElev = dElev ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) + return false ; + } + // per lame non è necessario + } + } + } + } return true ; } @@ -1172,19 +1728,42 @@ Milling::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, //---------------------------------------------------------------------------- bool -Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, Point3d& ptP1) +Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, bool bInvert, + Point3d& ptP1) { - switch ( m_Params.m_nLeadInType) { + // Assegno tipo e parametri + int nType = m_Params.m_nLeadInType ; + double dTang = m_Params.m_dLiTang ; + double dPerp = m_Params.m_dLiPerp ; + // se step invertito + if ( bInvert) { + switch ( m_Params.m_nLeadOutType) { + case MILL_LO_LINEAR : nType = MILL_LI_LINEAR ; break ; + case MILL_LO_TANGENT : nType = MILL_LI_TANGENT ; break ; + case MILL_LO_GLIDE : nType = MILL_LI_GLIDE ; break ; + case MILL_LO_AS_LI : /* resta inalterato */ ; break ; + default : nType = MILL_LI_NONE ; break ; + } + if ( m_Params.m_nLeadOutType != MILL_LO_AS_LI) { + dTang = m_Params.m_dLoTang ; + dPerp = m_Params.m_dLoPerp ; + } + } + // senso di rotazione da dir tg a dir esterna + bool bCcwRot = (( ! bInvert && m_Params.m_nWorkSide == MILL_WS_LEFT) || + ( bInvert && m_Params.m_nWorkSide != MILL_WS_LEFT)) ; + // Calcolo punto iniziale + switch ( nType) { case MILL_LI_NONE : ptP1 = ptStart ; return true ; case MILL_LI_LINEAR : case MILL_LI_TANGENT : { - if ( m_Params.m_dLiTang < 10 * EPS_SMALL && abs( m_Params.m_dLiPerp) < EPS_SMALL) + if ( dTang < 10 * EPS_SMALL && abs( dPerp) < 10 * EPS_SMALL) return false ; Vector3d vtPerp = vtStart ; - vtPerp.Rotate( vtN, ( ( m_Params.m_nWorkSide == MILL_WS_LEFT) ? 90 : - 90)) ; - ptP1 = ptStart - vtStart * m_Params.m_dLiTang + vtPerp * m_Params.m_dLiPerp ; + vtPerp.Rotate( vtN, ( bCcwRot ? 90 : - 90)) ; + ptP1 = ptStart - vtStart * dTang + vtPerp * dPerp ; return true ; } case MILL_LI_GLIDE : @@ -1198,17 +1777,28 @@ Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const //---------------------------------------------------------------------------- bool Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, - const Vector3d& vtN, bool bSplitArcs) + const Vector3d& vtN, bool bInvert, bool bSplitArcs) { - // assegno i parametri + // Assegno il tipo int nType = m_Params.m_nLeadInType ; + // se step invertito + if ( bInvert) { + switch ( m_Params.m_nLeadOutType) { + case MILL_LO_LINEAR : nType = MILL_LI_LINEAR ; break ; + case MILL_LO_TANGENT : nType = MILL_LI_TANGENT ; break ; + case MILL_LO_GLIDE : nType = MILL_LI_GLIDE ; break ; + case MILL_LO_AS_LI : /* resta inalterato */ ; break ; + default : nType = MILL_LI_NONE ; break ; + } + } + // se archi da spezzare if ( bSplitArcs) { if ( nType == MILL_LI_TANGENT) nType = MILL_LI_LINEAR ; if ( nType == MILL_LI_HELIX) - nType = MILL_LI_LINEAR ; // prevedere un nuovo tipo zig-zag + nType = MILL_LI_ZIGZAG ; } - // eseguo a seconda del tipo + // Eseguo a seconda del tipo switch ( nType) { case MILL_LI_NONE : return true ; @@ -1272,6 +1862,12 @@ Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& case MILL_LI_GLIDE : // !!! DA FARE !!! return false ; + case MILL_LI_ZIGZAG : + // !!! DA FARE !!! + return false ; + case MILL_LI_HELIX : + // !!! DA FARE !!! + return false ; default : return false ; } @@ -1280,14 +1876,22 @@ Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& //---------------------------------------------------------------------------- bool Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - Point3d& ptP1, bool bSplitArcs) + bool bInvert, bool bSplitArcs, Point3d& ptP1) { // assegno i parametri int nType = m_Params.m_nLeadOutType ; double dTang = m_Params.m_dLoTang ; double dPerp = m_Params.m_dLoPerp ; - if ( nType == MILL_LO_AS_LI) { - nType = m_Params.m_nLeadInType ; + // se uscita come ingresso o step invertito + if ( nType == MILL_LO_AS_LI || bInvert) { + switch ( m_Params.m_nLeadInType) { + case MILL_LI_LINEAR : nType = MILL_LO_LINEAR ; break ; + case MILL_LI_TANGENT : nType = MILL_LO_TANGENT ; break ; + case MILL_LI_GLIDE : nType = MILL_LO_GLIDE ; break ; + case MILL_LI_ZIGZAG : nType = MILL_LO_LINEAR ; break ; + case MILL_LI_HELIX : nType = MILL_LO_TANGENT ; break ; + default : nType = MILL_LO_NONE ; break ; + } dTang = m_Params.m_dLiTang ; dPerp = m_Params.m_dLiPerp ; } @@ -1295,6 +1899,9 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d if ( nType == MILL_LO_TANGENT) nType = MILL_LO_LINEAR ; } + // senso di rotazione da dir tg a dir esterna + bool bCcwRot = (( ! bInvert && m_Params.m_nWorkSide == MILL_WS_LEFT) || + ( bInvert && m_Params.m_nWorkSide != MILL_WS_LEFT)) ; // eseguo a seconda del tipo switch ( nType) { case MILL_LO_NONE : @@ -1305,7 +1912,7 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d if ( dTang < 10 * EPS_SMALL && abs( dPerp) < EPS_SMALL) return false ; Vector3d vtPerp = vtEnd ; - vtPerp.Rotate( vtN, ( ( m_Params.m_nWorkSide == MILL_WS_LEFT) ? 90 : - 90)) ; + vtPerp.Rotate( vtN, ( bCcwRot ? 90 : - 90)) ; ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp ; return ( AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ; } @@ -1315,7 +1922,7 @@ Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d if ( dTang < 10 * EPS_SMALL && abs( dPerp) < EPS_SMALL) return false ; Vector3d vtPerp = vtEnd ; - vtPerp.Rotate( vtN, ( ( m_Params.m_nWorkSide == MILL_WS_LEFT) ? 90 : - 90)) ; + vtPerp.Rotate( vtN, ( bCcwRot ? 90 : - 90)) ; ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp ; // inserisco uscita PtrOwner pCrv( GetArc2PVN( ptEnd, ptP1, vtEnd, vtN)) ; diff --git a/Milling.h b/Milling.h index c60a91e..c4411e1 100644 --- a/Milling.h +++ b/Milling.h @@ -18,6 +18,7 @@ #include "ToolData.h" class ICurve ; +class ICurveComposite ; //---------------------------------------------------------------------------- class Milling : public Machining @@ -65,13 +66,23 @@ class Milling : public Machining ICurve* GetCurve( SelData Id) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; + bool CalcElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double& dElev) ; + bool AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) ; + bool AddZigZagMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) ; + bool AddOneWayMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) ; + bool AddSpiralMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; - bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, Point3d& ptP1) ; + bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, bool bInvert, + Point3d& ptP1) ; bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, - const Vector3d& vtN, bool bSplitArcs) ; + const Vector3d& vtN, bool bInvert, bool bSplitArcs) ; bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - Point3d& ptP1, bool bSplitArcs) ; + bool bInvert, bool bSplitArcs, Point3d& ptP1) ; private : double GetSpeed() const diff --git a/MillingData.cpp b/MillingData.cpp index e680669..def30df 100644 --- a/MillingData.cpp +++ b/MillingData.cpp @@ -480,7 +480,8 @@ bool MillingData::VerifyLeadInType( int nVal) const { return ( nVal == MILL_LI_NONE || nVal == MILL_LI_LINEAR || - nVal == MILL_LI_TANGENT || nVal == MILL_LI_GLIDE) ; + nVal == MILL_LI_TANGENT || nVal == MILL_LI_GLIDE || + nVal == MILL_LI_ZIGZAG || nVal == MILL_LI_HELIX) ; } //---------------------------------------------------------------------------- @@ -488,7 +489,8 @@ bool MillingData::VerifyLeadOutType( int nVal) const { return ( nVal == MILL_LO_NONE || nVal == MILL_LO_LINEAR || - nVal == MILL_LO_TANGENT || nVal == MILL_LO_GLIDE || nVal == MILL_LO_AS_LI) ; + nVal == MILL_LO_TANGENT || nVal == MILL_LO_GLIDE || + nVal == MILL_LO_AS_LI) ; } //---------------------------------------------------------------------------- diff --git a/Operation.cpp b/Operation.cpp index 6b5c4b1..9c0406c 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -720,7 +720,7 @@ Operation::CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes, //---------------------------------------------------------------------------- bool -Operation::AdjustStartEndMovements(void) +Operation::AdjustStartEndMovements( bool bOnlyStart) { if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -819,6 +819,9 @@ Operation::AdjustStartEndMovements(void) if ( ! AdjustOneStartMovement( nClPathId, vAxVal, bHomeZ)) bOk = false ; bHomeZ = false ; + // se solo inizio, ho finito + if ( bOnlyStart) + return bOk ; // recupero nuovi finali if ( ! GetClPathFinalAxesValues( nClPathId, vAxVal)) bOk = false ; @@ -828,7 +831,26 @@ Operation::AdjustStartEndMovements(void) // aggiungo risalita finale bOk = bOk && AddRise( vAxVal) ; - bOk = bOk && AddHome() ; + + // recupero la lavorazione successiva non vuota + int nNextOpId = m_pMchMgr->GetNextActiveOperation( m_nOwnerId) ; + Operation* pNextOp = GetOperation( m_pGeomDB->GetUserObj( nNextOpId)) ; + while ( pNextOp != nullptr) { + if ( ! pNextOp->IsEmpty()) + break ; + else { + nNextOpId = m_pMchMgr->GetNextActiveOperation( nNextOpId) ; + pNextOp = GetOperation( m_pGeomDB->GetUserObj( nNextOpId)) ; + } + } + + // se non esiste lavorazione successiva, vado in home + if ( pNextOp == nullptr) + bOk = bOk && AddHome() ; + + // altrimenti aggiusto l'inizio della lavorazione successiva con il finale di questa + else + bOk = bOk && pNextOp->AdjustStartEndMovements( true) ; return bOk ; } diff --git a/Operation.h b/Operation.h index 987912b..fd24b31 100644 --- a/Operation.h +++ b/Operation.h @@ -69,7 +69,7 @@ class Operation : public IUserObj bool CalculateAxesValues( void) ; bool CalculateClPathAxesValues( int nClPathId, int nLinAxes, int nRotAxes, double dRot1W, DBLVECTOR& vAxRotPrec, int& nOutStrC) ; - bool AdjustStartEndMovements( void) ; + bool AdjustStartEndMovements( bool bOnlyStart = false) ; bool AdjustOneStartMovement( int nClPathId, const DBLVECTOR& vAxPrev, bool bHomeZ) ; bool ToolChangeNeeded( const Operation& Op1, const Operation& Op2) ; bool AddRise( DBLVECTOR& vAxVal, double dDelta = - 1) ;