From df5564c68d0c88c7be9b515cf361fb98fe3d3ca0 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 7 Feb 2017 12:13:37 +0000 Subject: [PATCH] EgtMachKernel : - sistemazioni per scalpellatura e svuotatura. --- Chseling.cpp => Chiseling.cpp | 705 ++++++++++++---------------------- Chiseling.h | 14 +- Drilling.cpp | 2 +- EgtMachKernel.vcxproj | 2 +- EgtMachKernel.vcxproj.filters | 4 +- Pocketing.cpp | 665 ++++++++++++++++++-------------- Pocketing.h | 10 +- 7 files changed, 633 insertions(+), 769 deletions(-) rename Chseling.cpp => Chiseling.cpp (63%) diff --git a/Chseling.cpp b/Chiseling.cpp similarity index 63% rename from Chseling.cpp rename to Chiseling.cpp index 84fc05d..74d71de 100644 --- a/Chseling.cpp +++ b/Chiseling.cpp @@ -31,6 +31,20 @@ using namespace std ; +//---------------------------------------------------------------------------- +struct SqHole +{ + Point3d ptIni ; // punto iniziale + Vector3d vtExtr ; // direzione di estrusione (dal fondo in su) + Vector3d vtAux ; // direzione ausiliaria di orientamento + Vector3d vtMove ; // direzione di movimento libero + double dLen ; // lunghezza dell'asse + SqHole( void) + : ptIni(), vtExtr(), vtAux(), vtMove(), dLen( 0) {} + SqHole( const Point3d ptI, const Vector3d& vtE, const Vector3d& vtA, const Vector3d& vtM, double dL) + : ptIni( ptI), vtExtr( vtE), vtAux( vtA), vtMove( vtM), dLen( dL) {} +} ; + //---------------------------------------------------------------------------- USEROBJ_REGISTER( "EMkChiseling", Chiseling) ; @@ -73,7 +87,7 @@ Chiseling::Dump( string& sOut, bool bMM, const char* szNewLine) const sOut += m_Params.ToString( i) + szNewLine ; for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) sOut += m_TParams.ToString( i) + szNewLine ; - sOut += KEY_NUM + EQUAL + ToString( m_nMills) + szNewLine ; + sOut += KEY_NUM + EQUAL + ToString( m_nChisels) + szNewLine ; return true ; } @@ -94,7 +108,7 @@ Chiseling::Save( STRVECTOR& vString) const vString[++k] = m_TParams.ToString( i) ; if ( ! SetVal( KEY_PHASE, m_nPhase, vString[++k])) return false ; - if ( ! SetVal( KEY_NUM, m_nMills, vString[++k])) + if ( ! SetVal( KEY_NUM, m_nChisels, vString[++k])) return false ; } catch( ...) { @@ -141,7 +155,7 @@ Chiseling::Load( const STRVECTOR& vString, int nBaseGdbId) return false ; } else if ( sKey == KEY_NUM) { - if ( ! FromString( sVal, m_nMills)) + if ( ! FromString( sVal, m_nChisels)) return false ; } } @@ -156,7 +170,7 @@ Chiseling::Chiseling( void) m_Params.m_sToolName = "*" ; m_TParams.m_sName = "*" ; m_TParams.m_sHead = "*" ; - m_nMills = 0 ; + m_nChisels = 0 ; } //---------------------------------------------------------------------------- @@ -263,6 +277,9 @@ Chiseling::SetParam( int nType, double dVal) case MPA_STEP : m_Params.m_dStep = dVal ; return true ; + case MPA_RETURNPOS : + m_Params.m_dReturnPos = dVal ; + return true ; case MPA_ENDADDLEN : m_Params.m_dEndAddLen = dVal ; return true ; @@ -328,7 +345,7 @@ bool Chiseling::Preview( bool bRecalc) { // reset numero percorsi di lavoro generati - m_nMills = 0 ; + m_nChisels = 0 ; // verifico validità gestore DB geometrico e Id del gruppo if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) @@ -390,8 +407,8 @@ Chiseling::Preview( bool bRecalc) bool Chiseling::Apply( bool bRecalc) { - // reset numero percorsi di lavoro generati - m_nMills = 0 ; + // reset numero scalpellature generate + m_nChisels = 0 ; // verifico validità gestore DB geometrico e Id del gruppo if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId)) @@ -447,7 +464,7 @@ Chiseling::Apply( bool bRecalc) } // se lavorazione vuota, esco - if ( m_nMills == 0) + if ( m_nChisels == 0) return true ; // calcolo gli assi macchina @@ -503,6 +520,9 @@ bool Chiseling::GetParam( int nType, double& dVal) const { switch ( nType) { + case MPA_SPEED : + dVal = 0 ; + return true ; case MPA_FEED : dVal = GetFeed() ; return true ; @@ -524,6 +544,9 @@ Chiseling::GetParam( int nType, double& dVal) const case MPA_STEP : dVal = m_Params.m_dStep ; return true ; + case MPA_RETURNPOS : + dVal = m_Params.m_dReturnPos ; + return true ; case MPA_ENDADDLEN : dVal = m_Params.m_dEndAddLen ; return true ; @@ -915,57 +938,15 @@ Chiseling::ProcessPath( int nPathId, int nPvId, int nClId) pCompo->Invert() ; // recupero estrusione e spessore - Vector3d vtExtr ; + Vector3d vtExtr = Z_AX ; pCompo->GetExtrusion( vtExtr) ; double dThick ; pCompo->GetThickness( dThick) ; - // se utensile non centrato, eseguo correzione raggio utensile ed eventuale offset - double dOffs = 0.5 * m_TParams.m_dDiam + GetOffsR() ; - if ( m_Params.m_nWorkSide != MILL_WS_CENTER && abs( dOffs) > EPS_SMALL) { - // valore offset - double dSignOffs = ( m_Params.m_nWorkSide == MILL_WS_RIGHT) ? dOffs : - dOffs ; - // flag offset - int nFlag = ICurve::OFF_EXTEND ; - // se percorso chiuso senza overlap ed inizio/fine è un angolo esterno - if ( pCompo->IsClosed()) { - Vector3d vtStart, vtEnd ; - if ( pCompo->GetStartDir( vtStart) && pCompo->GetEndDir( vtEnd) && - ( vtEnd ^ vtStart) * vtExtr * dSignOffs > 0) - nFlag += ICurve::OFF_FORCE_OPEN ; - } - // esecuzione offset - if ( ! pCompo->SimpleOffset( dSignOffs, nFlag)) { - // se curva piatta, provo con offset avanzato - bool bOk = false ; - Plane3d plPlane ; - if ( pCompo->IsFlat( plPlane, 100 * EPS_SMALL) && - AreSameOrOppositeVectorApprox( vtExtr, plPlane.vtN)) { - OffsetCurve OffsCrv ; - if ( OffsCrv.Make( pCompo, dSignOffs, nFlag)) { - ICurve* pOffs = OffsCrv.GetLongerCurve() ; - if ( pOffs != nullptr) { - pCompo->Clear() ; - pCompo->AddCurve( pOffs) ; - bOk = true ; - } - } - } - if ( ! bOk) { - LOG_INFO( GetEMkLogger(), "Error in Milling : Offset not computable") ; - return false ; - } - } - } - - // unisco le parti allineate (tranne inizio-fine se chiusa) - if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false)) + // unisco le parti allineate + if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL)) return false ; - // recupero il punto di inizio (per poi salvarlo nelle info di CL path) - Point3d ptStart ; - pCompo->GetStartPoint( ptStart) ; - // recupero il box del grezzo in globale BBox3d b3Raw ; if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dDiam, b3Raw) || b3Raw.IsEmpty()) { @@ -999,41 +980,8 @@ Chiseling::ProcessPath( int nPathId, int nPvId, int nClId) string sPathName ; m_pGeomDB->GetName( nPathId, sPathName) ; - // 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 ; - if ( pCompo->ApproxWithLines( 50 * EPS_SMALL, ANG_TOL_MAX_DEG, ICurve::APL_SPECIAL, PL)) { - // sostituisco le linee alle curve originali - pCompo->Clear() ; - pCompo->FromPolyLine( PL) ; - // riassegno estrusione e spessore - pCompo->SetExtrusion( vtExtr) ; - pCompo->SetThickness( dThick) ; - } - } - - // verifiche sull'ampiezza dell'angolo al centro degli eventuali archi - const double MAX_ANG_CEN = 150 + EPS_ANG_SMALL ; - int nMaxInd = pCompo->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // se arco con angolo al centro oltre il limite, lo divido a metà - const ICurveArc* pArc = GetCurveArc( pCompo->GetCurve( i)) ; - if ( pArc != nullptr && abs( pArc->GetAngCenter()) > MAX_ANG_CEN) { - pCompo->AddJoint( i + 0.5) ; - ++ i ; - ++ nMaxInd ; - } - } - - // calcolo il versore fresa - Vector3d vtTool = Z_AX ; - if ( ! vtExtr.IsSmall()) - vtTool = vtExtr ; + // assegno il versore fresa + Vector3d vtTool = vtExtr ; // calcolo l'elevazione massima double dElev ; @@ -1047,77 +995,120 @@ Chiseling::ProcessPath( int nPathId, int nPvId, int nClId) else return false ; - // per frese normali, verifico di non superare il massimo materiale - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - const double MAXMAT_TOL = EPS_SMALL ; - if ( ( m_Params.m_dStep < EPS_SMALL && dElev > m_TParams.m_dMaxMat + MAXMAT_TOL) || - ( m_Params.m_dStep > EPS_SMALL && m_Params.m_dStep > m_TParams.m_dMaxMat + EPS_SMALL)) { - if ( dDepth + max( dThick, 0.0) > m_TParams.m_dMaxMat) { - dDepth = m_TParams.m_dMaxMat - max( dThick, 0.0) ; - string sInfo = "Warning in Milling : machining depth (" + ToString( dElev, 1) + - ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; - LOG_INFO( GetEMkLogger(), sInfo.c_str()) ; - } - else { - string sInfo = "Error in Milling : machining depth (" + ToString( dElev, 1) + - ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; - LOG_INFO( GetEMkLogger(), sInfo.c_str()) ; - return false ; - } + // verifico di non superare il massimo materiale + const double MAXMAT_TOL = EPS_SMALL ; + if ( dElev > m_TParams.m_dMaxMat + MAXMAT_TOL) { + if ( dDepth + max( dThick, 0.0) > m_TParams.m_dMaxMat) { + dDepth = m_TParams.m_dMaxMat - max( dThick, 0.0) ; + dElev = m_TParams.m_dMaxMat ; + string sInfo = "Warning in Milling : machining depth (" + ToString( dElev, 1) + + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; + LOG_INFO( GetEMkLogger(), sInfo.c_str()) ; + } + else { + string sInfo = "Error in Milling : machining depth (" + ToString( dElev, 1) + + ") bigger than MaxMaterial (" + ToString( m_TParams.m_dMaxMat, 1) + ")" ; + LOG_INFO( GetEMkLogger(), sInfo.c_str()) ; + return false ; } } - // verifiche per fresatura dal basso - m_bAggrBottom = false ; - if ( ! VerifyPathFromBottom( pCompo, vtTool)) { - return false ; + // vettore dei fori quadrati + std::vector vSqHole ; + + // cerco gli angoli interni in cui fare la scalpellatura + const ICurve* pPrevCrv = pCompo->GetLastCurve() ; + const ICurve* pCurrCrv = pCompo->GetFirstCurve() ; + while ( pPrevCrv != nullptr && pCurrCrv != nullptr) { + // devono essere due rette + if ( pPrevCrv->GetType() == CRV_LINE && pCurrCrv->GetType() == CRV_LINE) { + // devono essere abbastanza lunghe e formare un angolo retto dalla parte della correzione + double dPrevLen ; pPrevCrv->GetLength( dPrevLen) ; + double dCurrLen ; pCurrCrv->GetLength( dCurrLen) ; + Vector3d vtPrevDir ; pPrevCrv->GetEndDir( vtPrevDir) ; + Vector3d vtCurrDir ; pCurrCrv->GetStartDir( vtCurrDir) ; + double dProVett = ( vtPrevDir ^ vtCurrDir) * vtExtr ; + const double SIN_ANG_LIM = sin( ( ANG_RIGHT - 100 * EPS_ANG_SMALL) * DEGTORAD) ; + if ( dPrevLen > 0.5 * m_TParams.m_dDiam - EPS_SMALL && + dCurrLen > 0.5 * m_TParams.m_dDiam - EPS_SMALL && + ( dProVett > SIN_ANG_LIM && m_Params.m_nWorkSide == CHISEL_WS_LEFT) || + ( dProVett < - SIN_ANG_LIM && m_Params.m_nWorkSide == CHISEL_WS_RIGHT)) { + Vector3d vtMid = Media( - vtPrevDir, vtCurrDir, 0.5) ; + Point3d ptIni ; pPrevCrv->GetEndPoint( ptIni) ; + ptIni += vtMid * m_TParams.m_dDiam + vtTool * ( dElev - dDepth) ; + vtMid.Normalize() ; + vSqHole.emplace_back( ptIni, vtTool, vtCurrDir, vtMid, dElev) ; + } + } + // passo alla coppia successiva + pPrevCrv = pCurrCrv ; + pCurrCrv = pCompo->GetNextCurve() ; + } + + // uniformo il vettore ausiliario + Frame3d frRef ; + frRef.Set( ORIG, vtTool) ; + Vector3d vtRef = frRef.VersY() ; + for ( size_t i = 0 ; i < vSqHole.size() ; ++ i) { + if ( AreSameOrOppositeVectorApprox( vSqHole[i].vtAux, vtRef) || + AreOrthoApprox( vSqHole[i].vtAux, vtRef)) + vSqHole[i].vtAux = vtRef ; + else + vtRef = vSqHole[i].vtAux ; + } + + // collasso i fori quadrati coincidenti + for ( size_t i = 1 ; i < vSqHole.size() ; ++ i) { + if ( AreSamePointApprox( vSqHole[i-1].ptIni, vSqHole[i].ptIni)) { + Vector3d vtMid = Media( vSqHole[i-1].vtMove, vSqHole[i].vtMove, 0.5) ; + vtMid.Normalize() ; + vSqHole[i-1].vtMove = vtMid ; + -- i ; + } } // se richiesta anteprima if ( nPvId != GDB_ID_NULL) { - // creo gruppo per geometria di lavorazione del percorso - int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nPvId, Frame3d()) ; - if ( nPxId == GDB_ID_NULL) - return false ; - m_pGeomDB->SetName( nPxId, sPathName) ; - m_pGeomDB->SetMaterial( nPxId, GREEN) ; - // creo l'anteprima del percorso - if ( ! GenerateMillingPv( nPxId, pCompo)) - return false ; + for ( size_t i = 0 ; i < vSqHole.size() ; ++ i) { + // creo gruppo per geometria di anteprima della scalpellatura + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nPvId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sPathName + "_" + ToString( int( i) + 1)) ; + m_pGeomDB->SetMaterial( nPxId, GREEN) ; + // creo l'anteprima delle scalpellature + if ( ! GenerateChiselingPv( vSqHole[i], nPxId)) + return false ; + } } // se richiesta lavorazione if ( nClId != GDB_ID_NULL) { - // creo gruppo per geometria di lavorazione del percorso - int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; - if ( nPxId == GDB_ID_NULL) - return false ; - m_pGeomDB->SetName( nPxId, sPathName) ; - m_pGeomDB->SetMaterial( nPxId, BLUE) ; + for ( size_t i = 0 ; i < vSqHole.size() ; ++ i) { - // assegno il vettore estrazione al gruppo del percorso - m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; - // assegno il punto di inizio al gruppo del percorso - m_pGeomDB->SetInfo( nPxId, KEY_START, ptStart) ; + // creo gruppo per geometria di lavorazione della scalpellatura + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sPathName + "_" + ToString( int( i) + 1)) ; + m_pGeomDB->SetMaterial( nPxId, GREEN) ; - // Imposto dati comuni - SetPathId( nPxId) ; - SetToolDir( vtTool) ; + // Calcolo la scalpellatura + if ( ! GenerateChiselingCl( vSqHole[i], nPxId)) + return false ; - // Una sola passata - if ( ! AddStandardMilling( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) - return false ; - - // assegno al gruppo l'ingombro del percorso di lavoro - BBox3d b3Grp ; - m_pGeomDB->GetGlobalBBox( nPxId, b3Grp) ; - m_pGeomDB->SetInfo( nPxId, KEY_PMIN, b3Grp.GetMin()) ; - m_pGeomDB->SetInfo( nPxId, KEY_PMAX, b3Grp.GetMax()) ; + // assegno il vettore estrazione al gruppo del percorso + m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; + // assegno il punto di inizio al gruppo del percorso + m_pGeomDB->SetInfo( nPxId, KEY_START, vSqHole[i].ptIni) ; + // assegno al gruppo l'ingombro del percorso di scalpellatura + BBox3d b3Grp ; + m_pGeomDB->GetGlobalBBox( nPxId, b3Grp) ; + m_pGeomDB->SetInfo( nPxId, KEY_PMIN, b3Grp.GetMin()) ; + m_pGeomDB->SetInfo( nPxId, KEY_PMAX, b3Grp.GetMax()) ; + } } - // incremento numero di fresate - ++ m_nMills ; - return true ; } @@ -1186,342 +1177,134 @@ Chiseling::CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtT //---------------------------------------------------------------------------- bool -Chiseling::VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) +Chiseling::GenerateChiselingPv( const SqHole& hole, int nPathId) { - // se non è fresatura dal basso in alto, esco - if ( vtTool.z > - 0.5) - return true ; - // se c'è tavola basculante, esco - bool bTabTilting = false ; - if ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTabTilting) && bTabTilting) - return true ; - // verifico se c'è rinvio da sotto - int nHeadId = m_pMchMgr->GetHeadId( m_TParams.m_sHead) ; - int nAgbType ; - if ( ! m_pGeomDB->GetInfo( nHeadId, "AGB_TYPE", nAgbType) || nAgbType == 0) { - string sOut = "Milling error : missing aggregate from bottom" ; - LOG_INFO( GetEMkLogger(), sOut.c_str()) ; - return false ; - } - // recupero la massima distanza consentita dal rinvio - double dAgbDmax = 0 ; - m_pGeomDB->GetInfo( nHeadId, "AGB_DMAX", dAgbDmax) ; - // calcolo la massima distanza minima del percorso dal contorno del grezzo - double dDist = 0 ; - Vector3d vtDir ; - int nMaxInd = pCompo->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = pCompo->GetCurve( i) ; - // considero inizio della prima curva, punto medio e fine di tutte - Point3d ptP ; - double dCurrDist = 0 ; - Vector3d vtCurrDir ; - if ( i == 0) { - pCrvC->GetStartPoint( ptP) ; - GetMinDistanceFromRawSide( m_nPhase, ptP, dCurrDist, vtCurrDir) ; - if ( dCurrDist > dDist) { - dDist = dCurrDist ; - vtDir = vtCurrDir ; - } - } - pCrvC->GetMidPoint( ptP) ; - GetMinDistanceFromRawSide( m_nPhase, ptP, dCurrDist, vtCurrDir) ; - if ( dCurrDist > dDist) { - dDist = dCurrDist ; - vtDir = vtCurrDir ; - } - pCrvC->GetEndPoint( ptP) ; - GetMinDistanceFromRawSide( m_nPhase, ptP, dCurrDist, vtCurrDir) ; - if ( dCurrDist > dDist) { - dDist = dCurrDist ; - vtDir = vtCurrDir ; - } - } - // se supera il limite, errore - if ( dDist > dAgbDmax) { - string sOut = "Milling error : path too far from part sides" ; - LOG_INFO( GetEMkLogger(), sOut.c_str()) ; - return false ; - } - // assegno direzione di accesso e segnalo utilizzo aggregato da sotto - SetAuxDir( vtDir) ; - m_bAggrBottom = true ; - return true ; -} - -//---------------------------------------------------------------------------- -bool -Chiseling::GenerateMillingPv( int nPathId, const ICurveComposite* pCompo) -{ - // creo copia della curva composita - PtrOwner< ICurve> pCrv( pCompo->Clone()) ; - if ( IsNull( pCrv)) - return false ; - // calcolo la regione - PtrOwner pSfr ; - pSfr.Set( GetSurfFlatRegionFromFatCurve( Release( pCrv), 0.5 * m_TParams.m_dDiam, false, false)) ; - if ( IsNull( pSfr)) - return false ; - // ne recupero il contorno - PtrOwner< ICurve> pCrv2 ; - pCrv2.Set( pSfr->GetLoop( 0, 0)) ; - if ( IsNull( pCrv2)) - return false ; - // inserisco la curva nel DB - int nC2Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrv2)) ; - if ( nC2Id == GDB_ID_NULL) + // calcolo punti notevoli + Point3d ptCen = hole.ptIni ; + Point3d ptCorner = hole.ptIni + hole.vtMove * ( m_TParams.m_dDiam * SQRT1_2 + m_Params.m_dEndAddLen) ; + // inserisco quadrato che rappresenta la scalpellatura + PtrOwner pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || + ! pCompo->PolygonCenterCorner( 4, ptCen, ptCorner, hole.vtExtr)) return false ; + // assegno il versore estrusione e lo spessore + pCompo->SetExtrusion( hole.vtExtr) ; + pCompo->SetThickness( - hole.dLen) ; + // inserisco nel DB + int nDriId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCompo)) ; // assegno nome e colore - m_pGeomDB->SetName( nC2Id, MCH_PV_CUT) ; - m_pGeomDB->SetMaterial( nC2Id, LIME) ; - // eventuali altri contorni ( interni di contornatura chiusa) - const int MAX_INT_LOOP = 1000 ; - for ( int i = 1 ; i <= MAX_INT_LOOP ; ++i) { - PtrOwner< ICurve> pCrv3 ; - pCrv3.Set( pSfr->GetLoop( 0, i)) ; - if ( IsNull( pCrv3)) - break ; - // inserisco la curva nel DB - int nC3Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrv3)) ; - if ( nC3Id == GDB_ID_NULL) - return false ; - // assegno nome e colore - m_pGeomDB->SetName( nC3Id, MCH_PV_CUT) ; - m_pGeomDB->SetMaterial( nC3Id, LIME) ; - } - // inserisco la regione nel DB - int nRId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pSfr)) ; - if ( nRId == GDB_ID_NULL) - return false ; - m_pGeomDB->SetName( nRId, MCH_PV_RCUT) ; - m_pGeomDB->SetMaterial( nRId, INVISIBLE) ; - // la copio anche come regione ridotta - int nRrId = m_pGeomDB->Copy( nRId, GDB_ID_NULL, nPathId) ; - if ( nRrId == GDB_ID_NULL) - return false ; - m_pGeomDB->SetName( nRrId, MCH_PV_RRCUT) ; - m_pGeomDB->SetMaterial( nRrId, INVISIBLE) ; + m_pGeomDB->SetName( nDriId, MCH_PV_CUT) ; + m_pGeomDB->SetMaterial( nDriId, LIME) ; + // incremento numero di scalpellature + ++ m_nChisels ; return true ; } //---------------------------------------------------------------------------- bool -Chiseling::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 - double dAppr = m_Params.m_dStartPos ; - - // ciclo sulle curve elementari - bool bClosed = pCompo->IsClosed() ; - int nMaxInd = pCompo->GetCurveCount() - 1 ; - 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) ; - // 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 ; - // aggiungo approccio per frese normali con spazio sopra attacco - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) - dStElev = dElev ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) - return false ; - } - // altrimenti, approccio per lame o diretto - else { - // affondo al punto iniziale - SetFlag( 0) ; - if ( AddRapidStart( ptP1) == GDB_ID_NULL) - return false ; - } - // aggiungo attacco - } - // 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 ; - // 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, GetRadiusForStartEndElevation(), dEndElev)) - dEndElev = dElev ; - dEndElev -= ( ptP1 - ptEnd) * vtExtr ; - // aggiungo retrazione - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) - return false ; - } - // per lame non è necessario - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -Chiseling::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) +Chiseling::GenerateChiselingCl( const SqHole& hole, int nPathId) { + // aggiusto alcuni parametri del ciclo di foratura + double dStdLen = hole.dLen ; + double dReturnPos = m_Params.m_dReturnPos ; + // imposto dati comuni + SetPathId( nPathId) ; + SetToolDir( hole.vtExtr) ; + SetAuxDir( hole.vtAux) ; + // 1 -> punto approccio SetFlag( 1) ; - // se con aggregato da sotto - if ( m_bAggrBottom) { - // ne recupero alcuni dati - double dAgbEncH = 0 ; - double dAgbEncV = 0 ; - m_pGeomDB->GetInfo( m_pMchMgr->GetHeadId( m_TParams.m_sHead), "AGB_ENCH", dAgbEncH) ; - m_pGeomDB->GetInfo( m_pMchMgr->GetHeadId( m_TParams.m_sHead), "AGB_ENCV", dAgbEncV) ; - // aggiuntivo in Z - double dAggZ = max( dElev + max( dSafeZ, dAppr), 0.) ; - // distanza dal bordo del pezzo - double dDistBottom ; - if ( ! GetDistanceFromRawSide( m_nPhase, ptP, m_vtAux, dDistBottom)) - dDistBottom = 0 ; - // pre-approccio - Point3d ptP0 = ptP - Z_AX * dAggZ + m_vtAux * ( dDistBottom + dAgbEncH + dAppr) ; - Point3d ptP00 = ptP0 + Z_AX * ( dAgbEncV + m_TParams.m_dLen + dAggZ) ; - Vector3d vtAux = m_vtAux ; - vtAux.Rotate( Z_AX, 90) ; - SetAuxDir( vtAux) ; - if ( AddRapidStart( ptP00, MCH_CL_AGB_DWN) == GDB_ID_NULL) - return false ; - vtAux.Rotate( Z_AX, - 90) ; - SetAuxDir( vtAux) ; - SetFlag( 0) ; - if ( AddRapidMove( ptP0, MCH_CL_AGB_IN) == GDB_ID_NULL) + double dAppr = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + Point3d ptP1 = hole.ptIni + hole.vtExtr * dAppr ; + if ( AddRapidStart( ptP1) == GDB_ID_NULL) + return false ; + SetFlag( 0) ; + // 2 -> punto fuori (se diverso dal precedente) + if ( m_Params.m_dStartPos < dAppr) { + Point3d ptP2 = hole.ptIni + hole.vtExtr * m_Params.m_dStartPos ; + if ( AddRapidMove( ptP2) == GDB_ID_NULL) return false ; } - // se sopra attacco c'è spazio per sicurezza o approccio - if ( dElev + max( dSafeZ, dAppr) > 10 * EPS_SMALL) { - // se distanza di sicurezza minore di distanza di inizio - if ( dSafeZ < dAppr + 10 * EPS_SMALL) { - // 1 -> punto sopra inizio - Point3d ptP1 = ptP + vtTool * ( dElev + dAppr) ; - if ( ( ! m_bAggrBottom && AddRapidStart( ptP1) == GDB_ID_NULL) || - ( m_bAggrBottom && AddRapidMove( ptP1) == GDB_ID_NULL)) + // ciclo di affondamento a step + const double MIN_STEP = 2 ; + const double APPR_STEP = 1 ; + const double MIN_MOVE = 1 ; + double dStep = max( m_Params.m_dStep, MIN_STEP) ; + int nStep = int( ceil( hole.dLen / dStep)) ; + dStep = hole.dLen / nStep ; + if ( dReturnPos < - dStep + APPR_STEP + MIN_MOVE) + dReturnPos = - dStep + APPR_STEP + MIN_MOVE ; + double dCurrLen = 0 ; + for ( int i = 1 ; i <= nStep ; ++ i) { + // se non è primo step faccio retrazione e riaffondo + if ( i != 1) { + // retrazione + SetFeed( GetEndFeed()) ; + SetFlag( 103) ; // punto di scarico truciolo + Point3d ptPr = hole.ptIni + hole.vtExtr * dReturnPos ; + if ( AddLinearMove( ptPr) == GDB_ID_NULL) + return false ; + // riaffondo + SetFeed( GetEndFeed()) ; + SetFlag( 0) ; + Point3d ptPa = hole.ptIni - hole.vtExtr * ( dCurrLen - APPR_STEP) ; + if ( AddLinearMove( ptPa) == GDB_ID_NULL) return false ; } - else { - // 1a -> punto sopra inizio - Point3d ptP1b = ptP + vtTool * ( dElev + dAppr) ; - Point3d ptP1a = ptP1b + vtTool * ( dSafeZ - dAppr) ; - if ( ( ! m_bAggrBottom && AddRapidStart( ptP1a) == GDB_ID_NULL) || - ( m_bAggrBottom && AddRapidMove( ptP1a) == GDB_ID_NULL)) - // 1b -> punto appena sopra inizio - if ( ( dElev + dAppr) > EPS_SMALL) { - SetFlag( 0) ; - if ( AddRapidMove( ptP1b) == GDB_ID_NULL) - return false ; - } - } - // affondo al punto iniziale - SetFlag( 0) ; - SetFeed( GetTipFeed()) ; - if ( AddLinearMove( ptP) == GDB_ID_NULL) - return false ; - } - else { - // affondo diretto al punto iniziale - SetFlag( 0) ; - if ( ( ! m_bAggrBottom && AddRapidStart( ptP) == GDB_ID_NULL) || - ( m_bAggrBottom && AddRapidMove( ptP) == GDB_ID_NULL)) - return false ; - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -Chiseling::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) -{ - // se sopra uscita c'è spazio per sicurezza o approccio - if ( dElev + max( dSafeZ, dAppr) > 10 * EPS_SMALL) { - if ( dSafeZ < dAppr + 10 * EPS_SMALL) { - // 4 -> movimento di risalita sopra il punto finale - SetFeed( GetEndFeed()) ; - Point3d ptP4 = ptP + vtTool * ( dElev + dAppr) ; + // lunghezza di fine step + double dEndLen = dCurrLen + dStep ; + // 4 -> punto termine velocità standard (se risulta) + if ( dCurrLen < dStdLen + EPS_SMALL) { + // lunghezza di esecuzione + double dLen = min( hole.dLen, dEndLen) ; + // determino se arrivo in fondo al foro + bool bHoleEnd = ( dLen > hole.dLen - EPS_SMALL) ; + // determino se arrivo in fondo allo step + bool bStepEnd = ( dLen > dEndLen - EPS_SMALL) ; + // assegno parametri + SetFeed( GetFeed()) ; + if ( bHoleEnd) + SetFlag( 101) ; // fondo del foro + else if ( bStepEnd) + SetFlag( 102) ; // fondo dello step + // movimento + Point3d ptP4 = hole.ptIni - hole.vtExtr * dLen ; if ( AddLinearMove( ptP4) == GDB_ID_NULL) return false ; - } - else { - // 4a -> movimento di risalita appena sopra il punto finale - Point3d ptP4a = ptP + vtTool * ( dElev + dAppr) ; - if ( dElev + dAppr > EPS_SMALL) { - SetFeed( GetEndFeed()) ; - if ( AddLinearMove( ptP4a) == GDB_ID_NULL) - return false ; - } - // 4b -> movimento di risalita sopra il punto finale - Point3d ptP4b = ptP4a + vtTool * ( dSafeZ - dAppr) ; - if ( AddRapidMove( ptP4b) == GDB_ID_NULL) - return false ; + // aggiorno posizione e verifico se step completato + dCurrLen = dLen ; + if ( bHoleEnd || bStepEnd) + continue ; } } - // se con aggregato da sotto - if ( m_bAggrBottom) { - // ne recupero alcuni dati - double dAgbEncH = 0 ; - double dAgbEncV = 0 ; - m_pGeomDB->GetInfo( m_pMchMgr->GetHeadId( m_TParams.m_sHead), "AGB_ENCH", dAgbEncH) ; - m_pGeomDB->GetInfo( m_pMchMgr->GetHeadId( m_TParams.m_sHead), "AGB_ENCV", dAgbEncV) ; - // aggiuntivo in Z - double dAggZ = max( dElev + max( dSafeZ, dAppr), 0.) ; - // distanza dal bordo del pezzo - double dDistBottom ; - if ( ! GetDistanceFromRawSide( m_nPhase, ptP, m_vtAux, dDistBottom)) - dDistBottom = 0 ; - // post-retract - Point3d ptP0 = ptP - Z_AX * dAggZ + m_vtAux * ( dDistBottom + dAgbEncH + dAppr) ; - Point3d ptP00 = ptP0 + Z_AX * ( dAgbEncV + m_TParams.m_dLen + dAggZ) ; - if ( AddRapidMove( ptP0, MCH_CL_AGB_OUT) == GDB_ID_NULL) - return false ; - Vector3d vtAux = m_vtAux ; - vtAux.Rotate( Z_AX, 90) ; - SetAuxDir( vtAux) ; - if ( AddRapidMove( ptP00, MCH_CL_AGB_UP) == GDB_ID_NULL) - return false ; - } + + // 5 -> piccola risalita + const double ADD_RETRACT = 1.0 ; + SetFeed( GetEndFeed()) ; + SetFlag( 0) ; + Point3d ptP5 = hole.ptIni - hole.vtExtr * ( dStdLen - ADD_RETRACT) ; + if ( AddLinearMove( ptP5) == GDB_ID_NULL) + return false ; + + // 6 -> movimento di lato + SetFeed( GetTipFeed()) ; + SetFlag( 0) ; + Point3d ptP6 = ptP5 + hole.vtMove * m_Params.m_dEndAddLen ; + if ( AddLinearMove( ptP6) == GDB_ID_NULL) + return false ; + + // 7 -> ritorno all'approccio del foro + SetFeed( GetEndFeed()) ; + SetFlag( 104) ; // risalita sopra il foro + Point3d ptP7 = ptP1 + hole.vtMove * m_Params.m_dEndAddLen ; + if ( AddLinearMove( ptP7) == GDB_ID_NULL) + return false ; + + // reset dati di movimento + ResetMoveData() ; + + // incremento numero di scalpellature + ++ m_nChisels ; + return true ; } diff --git a/Chiseling.h b/Chiseling.h index 4251d88..74511d5 100644 --- a/Chiseling.h +++ b/Chiseling.h @@ -17,6 +17,7 @@ #include "ChiselingData.h" #include "ToolData.h" +struct SqHole ; class ICurve ; class ICurveComposite ; @@ -34,7 +35,7 @@ class Chiseling : public Machining public : // Operation bool IsEmpty( void) const override - { return ( m_nMills == 0) ; } + { return ( m_nChisels == 0) ; } protected : // Operation int GetSolCh( void) const override @@ -68,12 +69,8 @@ class Chiseling : public Machining bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) ; - bool VerifyPathFromBottom( const ICurveComposite* pCompo, const Vector3d& vtTool) ; - bool GenerateMillingPv( int nPathId, const ICurveComposite* pCompo) ; - bool AddStandardMilling( 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 GenerateChiselingPv( const SqHole& hole, int nPathId) ; + bool GenerateChiselingCl( const SqHole& hole, int nPathId) ; double GetRadiusForStartEndElevation( void) ; private : @@ -92,6 +89,5 @@ class Chiseling : public Machining SELVECTOR m_vId ; // identificativi entità geometriche da lavorare ChiselingData m_Params ; // parametri lavorazione ToolData m_TParams ; // parametri utensile - int m_nMills ; // numero di percorsi di lavoro generati - bool m_bAggrBottom ; // flag di utilizzo dell'aggregato da sotto + int m_nChisels ; // numero di scalpellature generati } ; \ No newline at end of file diff --git a/Drilling.cpp b/Drilling.cpp index ccd0da7..e84556c 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -42,7 +42,7 @@ struct Hole // eventuale tipo ( standard, ribassato, svasato) Hole( void) : nOriId( GDB_ID_NULL), ptIni(), vtDir(), dDiam( 0), dLen( 0), bBlind( true) {} -}; +} ; //---------------------------------------------------------------------------- USEROBJ_REGISTER( "EMkDrilling", Drilling) ; diff --git a/EgtMachKernel.vcxproj b/EgtMachKernel.vcxproj index 2e4c38e..cb0e958 100644 --- a/EgtMachKernel.vcxproj +++ b/EgtMachKernel.vcxproj @@ -211,7 +211,7 @@ copy $(TargetPath) \EgtProg\Dll64 - + false false diff --git a/EgtMachKernel.vcxproj.filters b/EgtMachKernel.vcxproj.filters index 8a26ab0..2dd0d06 100644 --- a/EgtMachKernel.vcxproj.filters +++ b/EgtMachKernel.vcxproj.filters @@ -195,10 +195,10 @@ Source Files\Machinings - + Source Files\Operations - + Source Files\Operations diff --git a/Pocketing.cpp b/Pocketing.cpp index c149a70..b528be9 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -42,8 +42,12 @@ using namespace std ; // 2508 = "Error in Pocketing : Entity GetElevation" // 2509 = "Error in Pocketing : missing aggregate from bottom" // 2510 = "Error in Pocketing : path too far from part sides" -// 2511 = "Error in Pocketing : Offset not computable" -// 2512 = "Error in Pocketing : Toolpath not computable" +// 2511 = "Error in Pocketing : toolpath allocation failed" +// 2512 = "Error in Pocketing : Offset not computable" +// 2513 = "Error in Pocketing : Toolpath not computable" +// 2514 = "Error in Pocketing : LeadIn not computable" +// 2515 = "Error in Pocketing : LeadOut not computable" +// 2516 = "Error in Pocketing : Link not computable" //---------------------------------------------------------------------------- USEROBJ_REGISTER( "EMkPocketing", Pocketing) ; @@ -1143,9 +1147,19 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) SetPathId( nPxId) ; SetToolDir( vtTool) ; - // Se una sola passata - if ( ! AddSpiralIn( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) - return false ; + // Eseguo la lavorazione a seconda del tipo + switch ( m_Params.m_nSubType) { + case POCKET_SUB_ZIGZAG : + case POCKET_SUB_ONEWAY : + case POCKET_SUB_SPIRALIN : + if ( ! AddSpiralIn( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) + return false ; + break ; + case POCKET_SUB_SPIRALOUT : + if ( ! AddSpiralOut( pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) + return false ; + break ; + } // assegno al gruppo l'ingombro del percorso di lavoro BBox3d b3Grp ; @@ -1367,9 +1381,326 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - // curva di lavorazione + // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine PtrOwner pMCrv( CreateCurveComposite()) ; + PtrOwner pRCrv( CreateCurveComposite()) ; + if ( IsNull( pMCrv) || IsNull( pRCrv)) { + m_pMchMgr->SetLastError( 2511, "Error in Pocketing : toolpath allocation failed") ; + return false ; + } + if ( ! CalcSpiral( pCompo, Get( pMCrv), Get( pRCrv))) + return false ; + // determino numero e affondamento degli step + int nStep = 1 ; + if ( m_Params.m_dStep > 100 * EPS_SMALL) + nStep = max( 1, static_cast( ceil( dElev / m_Params.m_dStep))) ; + double dStep = dElev / nStep ; + + int nMaxInd = pMCrv->GetCurveCount() - 1 ; + int nMaxRInd = pRCrv->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 = pMCrv->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à + 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, ptP1)) + return false ; + // se primo step, approccio e affondo + if ( j == 1) { + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) + dStElev = dElev ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) + return false ; + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bSplitArcs)) { + m_pMchMgr->SetLastError( 2514, "Error in Pocketing : LeadIn not computable") ; + return false ; + } + } + // altrimenti solo collegamento + else { + // per ora solo collegamento diretto !!! da estendere !!! + SetFeed( GetStartFeed()) ; + if ( AddLinearMove( ptP1) == GDB_ID_NULL) { + m_pMchMgr->SetLastError( 2516, "Error in Pocketing : Link 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à + if ( i == nMaxInd) { + // se step intermedio, ritorno all'inizio direttamente + if ( j < nStep) { + // ciclo sulle curve elementari del percorso di ritorno + for ( int k = 0 ; k <= nMaxRInd ; ++ k) { + // curva corrente + const ICurve* pCrvR = pRCrv->GetCurve( k) ; + // copio la curva + PtrOwner pRet( ::GetCurve( pCrvR->Clone())) ; + if ( IsNull( pRet)) + return false ; + // aggiungo affondamento + pRet->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // elaborazioni sulla curva corrente + if ( pRet->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pRet) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pRet->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pRet) ; + 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 ; + } + } + } + // atrimenti ultimo step, uscita e retrazione + else { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + SetFeed( GetStartFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, ptP1)) { + m_pMchMgr->SetLastError( 2515, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + // determino elevazione su fine uscita + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) + dEndElev = dElev ; + dEndElev -= ( ptP1 - ptEnd) * vtExtr ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) + return false ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::AddSpiralOut( 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 ; + + // calcolo la spirale dall'interno all'esterno + PtrOwner pMCrv( CreateCurveComposite()) ; + PtrOwner pRCrv( CreateCurveComposite()) ; + if ( IsNull( pMCrv) || IsNull( pRCrv)) { + m_pMchMgr->SetLastError( 2511, "Error in Pocketing : toolpath allocation failed") ; + return false ; + } + if ( ! CalcSpiral( pCompo, Get( pMCrv), Get( pRCrv))) + return false ; + pMCrv->Invert() ; + pRCrv->Invert() ; + + // determino numero e affondamento degli step + int nStep = 1 ; + if ( m_Params.m_dStep > 100 * EPS_SMALL) + nStep = max( 1, static_cast( ceil( dElev / m_Params.m_dStep))) ; + double dStep = dElev / nStep ; + + int nMaxInd = pMCrv->GetCurveCount() - 1 ; + int nMaxRInd = pRCrv->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 = pMCrv->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à + 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, ptP1)) + return false ; + // se primo step, approccio e affondo + if ( j == 1) { + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) + dStElev = dElev ; + dStElev -= ( ptP1 - ptStart) * vtExtr ; + // approccio al punto iniziale + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) + return false ; + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bSplitArcs)) { + m_pMchMgr->SetLastError( 2514, "Error in Pocketing : LeadIn not computable") ; + return false ; + } + } + // altrimenti solo collegamento + else { + // per ora solo collegamento diretto !!! da estendere !!! + SetFeed( GetStartFeed()) ; + if ( AddLinearMove( ptP1) == GDB_ID_NULL) { + m_pMchMgr->SetLastError( 2516, "Error in Pocketing : Link 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à + if ( i == nMaxInd) { + // se step intermedio, ritorno all'inizio direttamente + if ( j < nStep) { + // ciclo sulle curve elementari del percorso di ritorno + for ( int k = 0 ; k <= nMaxRInd ; ++ k) { + // curva corrente + const ICurve* pCrvR = pRCrv->GetCurve( k) ; + // copio la curva + PtrOwner pRet( ::GetCurve( pCrvR->Clone())) ; + if ( IsNull( pRet)) + return false ; + // aggiungo affondamento + pRet->Translate( - vtTool * ( dDepth - dElev + j * dStep)) ; + // elaborazioni sulla curva corrente + if ( pRet->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pRet) ; + Point3d ptP3 = pLine->GetEnd() ; + SetFeed( GetFeed()) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + } + else if ( pRet->GetType() == CRV_ARC) { + ICurveArc* pArc = GetCurveArc( pRet) ; + 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 ; + } + } + } + // atrimenti ultimo step, uscita e retrazione + else { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // aggiungo uscita + Point3d ptP1 ; + SetFeed( GetStartFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, ptP1)) { + m_pMchMgr->SetLastError( 2515, "Error in Pocketing : LeadOut not computable") ; + return false ; + } + // determino elevazione su fine uscita + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) + dEndElev = dElev ; + dEndElev -= ( ptP1 - ptEnd) * vtExtr ; + // aggiungo retrazione + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) + return false ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +Pocketing::CalcSpiral( const ICurveComposite* pCompo, ICurveComposite* pMCrv, ICurveComposite* pRCrv) +{ // primo offset pari al raggio utensile + sovramateriale double dOffs = 0.5 * m_TParams.m_dDiam + GetOffsR() ; @@ -1383,7 +1714,7 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c // calcolo OffsetCurve OffsCrv ; if ( ! OffsCrv.Make( pCurr, - dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 2511, "Error in Pocketing : Offset not computable") ; + m_pMchMgr->SetLastError( 2512, "Error in Pocketing : Offset not computable") ; return false ; } // accodo la curva offsettata al percorso di lavoro @@ -1392,8 +1723,14 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c if ( pMCrv->GetCurveCount() > 0) { Point3d ptStart ; pOffs->GetStartPoint( ptStart) ; + // aggiungo al percorso principale pMCrv->AddLine( ptStart) ; + // copio nel percorso di ritorno + pRCrv->AddCurve( *pMCrv->GetLastCurve()) ; } + // se richiesta percorrenza invertita + if ( m_Params.m_bInvert) + pOffs->Invert() ; // aggiungo la curva pMCrv->AddCurve( Release( pOffs)) ; } @@ -1413,91 +1750,13 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c // verifico il percorso di lavoro if ( pMCrv->GetCurveCount() == 0) { - m_pMchMgr->SetLastError( 2512, "Error in Pocketing : Toolpath not computable") ; + m_pMchMgr->SetLastError( 2513, "Error in Pocketing : Toolpath not computable") ; return false ; } + // compatto e inverto il percorso di ritorno + pRCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false) ; + pRCrv->Invert() ; - // ciclo sulle curve elementari - int nMaxInd = pMCrv->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = pMCrv->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( ::GetCurve( pCrvC->Clone())) ; - if ( IsNull( pCurve)) - return false ; - // aggiungo affondamento - pCurve->Translate( - vtTool * dDepth) ; - // 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 ; - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dStElev)) - dStElev = dElev ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // approccio al punto iniziale - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) - 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 ; - } - // determino elevazione su fine uscita - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), dEndElev)) - dEndElev = dElev ; - dEndElev -= ( ptP1 - ptEnd) * vtExtr ; - // aggiungo retrazione - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) - return false ; - // per lame non è necessario - } - } return true ; } @@ -1628,44 +1887,26 @@ Pocketing::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ //---------------------------------------------------------------------------- bool -Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, bool bInvert, - Point3d& ptP1) +Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, + Point3d& ptP1) { // Assegno tipo e parametri int nType = m_Params.m_nLeadInType ; - double dTang = m_Params.m_dLiTang ; - double dPerp = 0 ; - double dElev = 0 ; - // 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 = 0 ; - dElev = 0 ; - } - } + double dLen= m_Params.m_dLiTang ; // senso di rotazione da dir tg a dir esterna bool bCcwRot = true ; // Calcolo punto iniziale switch ( nType) { - case MILL_LI_NONE : + case POCKET_LI_NONE : ptP1 = ptStart ; return true ; - case MILL_LI_LINEAR : - case MILL_LI_TANGENT : { - Vector3d vtPerp = vtStart ; - vtPerp.Rotate( vtN, ( bCcwRot ? 90 : - 90)) ; - ptP1 = ptStart - vtStart * dTang + vtPerp * dPerp + vtN * dElev ; - return true ; - } - case MILL_LI_GLIDE : + case POCKET_LI_GLIDE : + + return false ; + case POCKET_LI_ZIGZAG : + // !!! DA FARE !!! + return false ; + case POCKET_LI_HELIX : // !!! DA FARE !!! return false ; default : @@ -1676,98 +1917,29 @@ Pocketing::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, con //---------------------------------------------------------------------------- bool Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, - const Vector3d& vtN, bool bInvert, bool bSplitArcs) + const Vector3d& vtN, bool bSplitArcs) { // 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_ZIGZAG ; + if ( nType == POCKET_LI_HELIX) + nType = POCKET_LI_ZIGZAG ; } - // se parametri tg e perp entrambi nulli, allora nessun attacco + // se parametro tg nullo, allora nessun attacco if ( (( ptStart - ptP1) ^ vtN).IsSmall()) - nType = MILL_LI_NONE ; + nType = POCKET_LI_NONE ; // Eseguo a seconda del tipo switch ( nType) { - case MILL_LI_NONE : + case POCKET_LI_NONE : return true ; - case MILL_LI_LINEAR : - return ( AddLinearMove( ptStart, MCH_CL_LEADIN) != GDB_ID_NULL) ; - case MILL_LI_TANGENT : - { - PtrOwner pCrv( GetArc2PVN( ptStart, ptP1, - vtStart, vtN)) ; - if ( IsNull( pCrv)) - return false ; - pCrv->Invert() ; - if ( pCrv->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCrv) ; - Point3d ptP3 = pLine->GetEnd() ; - return ( AddLinearMove( ptP3, MCH_CL_LEADIN) != GDB_ID_NULL) ; - } - else if ( pCrv->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCrv) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3) ; - // se angolo al centro minore del limite, un solo arco - const double MAX_ANG_CEN = 150 + EPS_ANG_SMALL ; - if ( abs( dAngCen) < MAX_ANG_CEN) { - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - } - // altrimenti due archi - else if ( abs( dAngCen) < 2 * MAX_ANG_CEN){ - Point3d ptMid ; - pArc->GetMidPoint( ptMid) ; - // prima metà arco - if ( AddArcMove( ptMid, ptCen, dAngCen / 2, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - // seconda metà arco - if ( AddArcMove( ptP3, ptCen, dAngCen / 2, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - } - // oppure tre archi - else { - Point3d ptTmp ; - // primo terzo - pArc->GetPointD1D2( 1. / 3, ICurve::FROM_MINUS, ptTmp) ; - if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - // secondo terzo - ptCen.z = ptTmp.z ; - pArc->GetPointD1D2( 2. / 3, ICurve::FROM_MINUS, ptTmp) ; - if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - // ultimo terzo - ptCen.z = ptTmp.z ; - if ( AddArcMove( ptP3, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL) - return false ; - } - return true ; - } - } - case MILL_LI_GLIDE : + case POCKET_LI_GLIDE : // !!! DA FARE !!! return false ; - case MILL_LI_ZIGZAG : + case POCKET_LI_ZIGZAG : // !!! DA FARE !!! return false ; - case MILL_LI_HELIX : + case POCKET_LI_HELIX : // !!! DA FARE !!! return false ; default : @@ -1778,113 +1950,24 @@ Pocketing::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3 //---------------------------------------------------------------------------- bool Pocketing::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - bool bInvert, bool bSplitArcs, Point3d& ptP1) + Point3d& ptP1) { // assegno i parametri int nType = m_Params.m_nLeadOutType ; double dTang = m_Params.m_dLoTang ; double dPerp = 0 ; double dElev = 0 ; - // 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 = 0 ; - dElev = 0 ; - } - if ( bSplitArcs) { - if ( nType == MILL_LO_TANGENT) - nType = MILL_LO_LINEAR ; - } - // se parametri nulli, allora nessuna uscita - if ( abs( dTang) < EPS_SMALL && abs( dPerp) < EPS_SMALL ) - nType = MILL_LO_NONE ; + // se parametrt tg nullo, allora nessuna uscita + if ( abs( dTang) < EPS_SMALL) + nType = POCKET_LO_NONE ; // senso di rotazione da dir tg a dir esterna bool bCcwRot = true ; // eseguo a seconda del tipo switch ( nType) { - case MILL_LO_NONE : + case POCKET_LO_NONE : ptP1 = ptEnd ; return true ; - case MILL_LO_LINEAR : - { - if ( dTang < 10 * EPS_SMALL && abs( dPerp) < EPS_SMALL) - return false ; - Vector3d vtPerp = vtEnd ; - vtPerp.Rotate( vtN, ( bCcwRot ? 90 : - 90)) ; - ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtN * dElev ; - return ( AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ; - } - case MILL_LO_TANGENT : - { - // calcolo punto finale dell'uscita - if ( dTang < 10 * EPS_SMALL && abs( dPerp) < EPS_SMALL) - return false ; - Vector3d vtPerp = vtEnd ; - vtPerp.Rotate( vtN, ( bCcwRot ? 90 : - 90)) ; - ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp + vtN * dElev ; - // inserisco uscita - PtrOwner pCrv( GetArc2PVN( ptEnd, ptP1, vtEnd, vtN)) ; - if ( IsNull( pCrv)) - return false ; - if ( pCrv->GetType() == CRV_LINE) { - ICurveLine* pLine = GetCurveLine( pCrv) ; - Point3d ptP3 = pLine->GetEnd() ; - return ( AddLinearMove( ptP3, MCH_CL_LEADOUT) != GDB_ID_NULL) ; - } - else if ( pCrv->GetType() == CRV_ARC) { - ICurveArc* pArc = GetCurveArc( pCrv) ; - Point3d ptCen = pArc->GetCenter() ; - double dAngCen = pArc->GetAngCenter() ; - Vector3d vtN = pArc->GetNormVersor() ; - Point3d ptP3 ; - pArc->GetEndPoint( ptP3) ; - // se angolo al centro minore del limite, un solo arco - const double MAX_ANG_CEN = 150 + EPS_ANG_SMALL ; - if ( abs( dAngCen) < MAX_ANG_CEN) { - if ( AddArcMove( ptP3, ptCen, dAngCen, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - } - // altrimenti due archi - else if ( abs( dAngCen) < 2 * MAX_ANG_CEN){ - Point3d ptMid ; - pArc->GetMidPoint( ptMid) ; - // prima metà arco - if ( AddArcMove( ptMid, ptCen, dAngCen / 2, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - // seconda metà arco - ptCen.z = ptMid.z ; - if ( AddArcMove( ptP3, ptCen, dAngCen / 2, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - } - // oppure tre archi - else { - Point3d ptTmp ; - // primo terzo - pArc->GetPointD1D2( 1. / 3, ICurve::FROM_MINUS, ptTmp) ; - if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - // secondo terzo - ptCen.z = ptTmp.z ; - pArc->GetPointD1D2( 2. / 3, ICurve::FROM_MINUS, ptTmp) ; - if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - // ultimo terzo - ptCen.z = ptTmp.z ; - if ( AddArcMove( ptP3, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL) - return false ; - } - return true ; - } - } - case MILL_LO_GLIDE : + case POCKET_LO_GLIDE : // !!! DA FARE !!! return false ; default : diff --git a/Pocketing.h b/Pocketing.h index a8a2501..3241644 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -72,14 +72,16 @@ class Pocketing : public Machining bool GenerateMillingPv( int nPathId, const ICurveComposite* pCompo) ; bool AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, bool bSplitArcs) ; + bool AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) ; + bool CalcSpiral( const ICurveComposite* pCompo, ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; 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, bool bInvert, - Point3d& ptP1) ; + bool CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, Point3d& ptP1) ; bool AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, - const Vector3d& vtN, bool bInvert, bool bSplitArcs) ; + const Vector3d& vtN, bool bSplitArcs) ; bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, - bool bInvert, bool bSplitArcs, Point3d& ptP1) ; + Point3d& ptP1) ; double GetRadiusForStartEndElevation( void) ; private :