From a4b462d6aba837e2c317ed1de402f12d65b813d3 Mon Sep 17 00:00:00 2001 From: SaraP Date: Fri, 25 Feb 2022 12:51:05 +0100 Subject: [PATCH] EgtMachKernel 2.4b7 : - in Pocketing aggiunta svuotatura a spirale ottimizzata nel caso di trapezoidi. --- EgtMachKernel.rc | Bin 11774 -> 11774 bytes Pocketing.cpp | 354 +++++++++++++++++++++++++++++++++++++++++++---- Pocketing.h | 15 +- 3 files changed, 340 insertions(+), 29 deletions(-) diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index cc9055a64bab29e0350176a7ff8599f53695d42d..d5689997494afcfb63514663f0dee1f005de6d1f 100644 GIT binary patch delta 241 zcmewt{V#gMI%aiGhCGIJh8%`ehGHOAV9;O)W+-7u1ma8}FBB-731Uz7R&U)L$1;bB z(R}l7Hd|&!^T`h-bvLJRO<)0wTx6PjLa+cPDg+fpQs=?Ad6l#WP#;h`nqrWY@;63e oowE6~YB8f=KG?0EV7KM~-I%!9TYV!lrtsv`ss}fp(l%iN0B*)aNdN!< delta 236 zcmewt{V#gMI%aKGhCGIJh8%`WhGK>c1_cHUhESkLCPN8BDnkm89}HwAf_cT0IklxX ze_&=~W;EOUUhX2(<& nF)y2}rOv|(a;PWRX*mp)AcsxGetCurrMachiningsMgr()->GetSafeZ() ; @@ -3257,7 +3258,8 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; } - if ( ! CalcSpiral( pCompo, nReg, bSplitArcs, pMCrv, pRCrv)) + bool bOptimizedTrap = false ; + if ( ! CalcSpiral( pCompo, nReg, bSplitArcs, pMCrv, pRCrv, nPathId, bOptimizedTrap)) return false ; // se terminate le regioni, esco if ( pMCrv->GetCurveCount() == 0) @@ -3274,9 +3276,9 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c } } - // se prima regione e gestione lato aperto + // se prima regione e gestione lato aperto ( caso non ottimizzato) bool bOutStart = ( nReg == 1 && bMidOpen) ; - if ( bOutStart) { + if ( bOutStart && ! bOptimizedTrap) { // calcolo il punto fuori Point3d ptOut = ptMidOpen + vtMidOut * ( 0.5 * m_TParams.m_dDiam + dSafeZ) ; // verifico che il punto sia veramente fuori dal grezzo @@ -3295,6 +3297,13 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c bOutStart = false ; } + // calcolo gli eventuali punti fuori dal grezzo nel caso ottimizzato + int nOutsideRaw = 0 ; + if ( bOptimizedTrap) { + AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; + bOutStart = ( nOutsideRaw > 0) ; + } + // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) { if ( ! LeadInIsOk()) { @@ -3314,6 +3323,9 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c // ciclo sugli step Point3d ptP1 ; for ( int j = 1 ; j <= nStep ; ++ j) { + // se sono nel caso ottimizzato e ho attacco e uscita entrambi dentro/fuori dal grezzo, ad ogni step inverto la direzione della curva + if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1) + pMCrv->Invert() ; // ciclo sulle curve elementari for ( int i = 0 ; i <= nMaxInd ; ++ i) { // curva corrente @@ -3450,22 +3462,14 @@ Pocketing::AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, c //---------------------------------------------------------------------------- bool Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, double dOkStep, bool bSplitArcs) + double dDepth, double dElev, double dOkStep, bool bSplitArcs, int nPathId) { // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - - // se utensile che non lavora di testa poichè ingresso non fuori dal pezzo, errore - if ( m_TParams.m_nType == TT_MILL_NOTIP) { - if ( ! LeadInIsOk()) { - m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; - return false ; - } - } - + // ciclo sulle regioni const int MAX_REGS = 50 ; int nReg = 0 ; @@ -3490,7 +3494,8 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, m_TParams.m_dDiam += 2 * m_Params.m_dEpicyclesRad ; } - if ( ! CalcSpiral( pCompo, nReg, bSplitArcs, pMCrv, pRCrv)) + bool bOptimizedTrap = false ; + if ( ! CalcSpiral( pCompo, nReg, bSplitArcs, pMCrv, pRCrv, nPathId, bOptimizedTrap)) return false ; // se terminate le regioni, esco if ( pMCrv->GetCurveCount() == 0) @@ -3506,11 +3511,29 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, return false ; } } - - // inverto i percorsi, perchè sono calcolati dall'esterno all'interno - pMCrv->Invert() ; - pRCrv->Invert() ; + // nel caso ottimizzato verifico se posso entrare e uscire fuori dal grezzo + bool bOutStart = false ; + int nOutsideRaw = 0 ; + if ( bOptimizedTrap) { + AdjustTrapezoidSpiralForLeadInLeadOut( pMCrv, pRCrv, vtTool, dDepth, nOutsideRaw) ; + bOutStart = ( nOutsideRaw > 0) ; + } + + // se utensile che non lavora di testa e ingresso non fuori dal pezzo, errore + if ( m_TParams.m_nType == TT_MILL_NOTIP && ! bOutStart) { + if ( ! LeadInIsOk()) { + m_pMchMgr->SetLastError( 2431, "Error in Pocketing : LeadIn with Mill NoTip in material") ; + return false ; + } + } + + // inverto i percorsi, perchè sono calcolati dall'esterno all'interno (solo nel caso non ottimizzato) + if ( ! bOptimizedTrap) { + pMCrv->Invert() ; + pRCrv->Invert() ; + } + // determino numero e affondamento degli step int nStep = 1 ; nStep = max( 1, static_cast( ceil( dElev / dOkStep))) ; @@ -3522,6 +3545,9 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, // ciclo sugli step Point3d ptP1 ; for ( int j = 1 ; j <= nStep ; ++ j) { + // se sono nel caso ottimizzato e ho attacco e uscita entrambi dentro/fuori dal grezzo, ad ogni step inverto la direzione della curva + if ( bOptimizedTrap && nOutsideRaw != 1 && j > 1) + pMCrv->Invert() ; // ciclo sulle curve elementari for ( int i = 0 ; i <= nMaxInd ; ++ i) { // curva corrente @@ -3569,7 +3595,7 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, } // aggiungo attacco SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, m_Params.m_bInvert, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ; return false ; } @@ -3578,7 +3604,7 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, else { SetFeed( GetStartFeed()) ; GetCurrPos( ptP1) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, m_Params.m_bInvert, bSplitArcs)) { + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo, pRCrv, m_Params.m_bInvert, bSplitArcs, bOutStart)) { m_pMchMgr->SetLastError( 2418, "Error in Pocketing : Link not computable") ; return false ; } @@ -3659,8 +3685,8 @@ Pocketing::AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, //---------------------------------------------------------------------------- bool -Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, - ICurveComposite* pMCrv, ICurveComposite* pRCrv) +Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, + ICurveComposite* pMCrv, ICurveComposite* pRCrv, int nPathId, bool& bOptimizedTrap) { // inizializzo i risultati pMCrv->Clear() ; @@ -3684,6 +3710,35 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, return true ; } + // recupero la curva originaria della svuotatura per verificare caso trapezoide + int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; + PtrOwner pCrvPocket( CloneCurveComposite( m_pGeomDB->GetGeoObj( nCrvId))) ; + if ( IsNull( pCrvPocket)) + return false ; + SetCurveAllTempProp( nCrvId, pCrvPocket) ; + pCrvPocket->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; + + Point3d pt ; + Vector3d vtB1, vtL1, vtB2 ; + if ( pCrvPocket->IsATrapezoid( 100 * EPS_SMALL, pt, vtB1, vtL1, vtB2)) { + Vector3d vtDir( vtB1), vtOtherDir( vtL1) ; + // se parallelogramma scelgo come base i lati lunghi + Vector3d vtL2( -vtB1 + vtL1 + vtB2) ; + if ( AreSameOrOppositeVectorApprox( vtL1, vtL2)) { + if ( vtL1.Len() > vtB1.Len()) + swap( vtDir, vtOtherDir) ; + } + vtDir.Normalize() ; + Vector3d vtOrtho = OrthoCompo( vtOtherDir, vtDir) ; + double dPocketSize = vtOrtho.Len() ; + if ( dPocketSize < m_TParams.m_dDiam + EPS_SMALL) { + if ( nReg == 0) + return CalcTrapezoidSpiral( pCrvPocket, vtDir, dPocketSize, pMCrv, pRCrv, bOptimizedTrap) ; + else + return true ; + } + } + // ciclo di offset verso l'interno const int MAX_ITER = 1000 ; int nIter = 0 ; @@ -4038,6 +4093,255 @@ Pocketing::CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double d return true ; } +//---------------------------------------------------- +bool +Pocketing::CalcTrapezoidSpiral( ICurveComposite * pCrvPocket, const Vector3d& vtDir, double dPocketSize, + ICurveComposite * pMCrv, ICurveComposite * pRCrv, bool& bOptimizedTrap) +{ + Vector3d vtExtr ; pCrvPocket->GetExtrusion( vtExtr) ; + // eventuale approssimazione della curva con polyline per ottenere la stessa curva calcolata in ICurveComposite::IsATrapezoid + if ( pCrvPocket->GetCurveCount() > 4) { + PolyLine PL ; + if ( ! pCrvPocket->ApproxWithLines( 100 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) + return false ; + pCrvPocket->Clear() ; + pCrvPocket->FromPolyLine( PL) ; + pCrvPocket->SetExtrusion( vtExtr) ; + } + + // sistemo senso antiorario visto dalla direzione di estrusione + Plane3d plPlane ; double dArea ; + pCrvPocket->GetArea( plPlane, dArea) ; + if ( plPlane.GetVersN() * vtExtr * dArea < 0) + pCrvPocket->Invert() ; + + // passo in un sistema di riferimento locale avente asse X allineato con uno dei due lati paralleli (possibilmente aperto) e centro nel + // punto iniziale del lato + Frame3d frLoc ; + if ( ! CalcTrapezoidSpiralLocalFrame( pCrvPocket, vtDir, frLoc)) + return false ; + pCrvPocket->ToLoc( frLoc) ; + + int nProp0 = 0, nProp1 = 0, nProp3 = 0 ; + pCrvPocket->GetCurveTempProp( 0, nProp0) ; + pCrvPocket->GetCurveTempProp( 1, nProp1) ; + pCrvPocket->GetCurveTempProp( 3, nProp3) ; + // verifico le dimensioni della svuotatura + if ( ! nProp0 && abs( dPocketSize - m_TParams.m_dDiam) > EPS_SMALL) + return false ; + + // calcolo percorso di svuotatura + double dYCoord = dPocketSize - 0.5 * m_TParams.m_dDiam ; + if ( nProp0) + dYCoord -= GetOffsR() ; + double dXCoordStart, dXCoordEnd ; + if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, true, dYCoord, dXCoordStart)) + return false ; + if ( ! CalcTrapezoidSpiralXCoord( pCrvPocket, false, dYCoord, dXCoordEnd)) + return false ; + Point3d ptStart( dXCoordStart, dYCoord) ; + Point3d ptEnd( dXCoordEnd, dYCoord) ; + + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine)) + return false ; + pLine->Set( ptStart, ptEnd) ; + + pMCrv->AddCurve( Release( pLine)) ; + pMCrv->ToGlob( frLoc) ; + if ( ! m_Params.m_bInvert) { + pMCrv->Invert() ; + // inverto le proprietà in modo che nProp3 sia sempre legata al punto iniziale e nProp1 a quello finale + swap( nProp1, nProp3) ; + } + // segno i lati aperti come temp prop della curva + int nOpenEdges = nProp0 + nProp1 * 2 + nProp3 * 8 ; + pMCrv->SetTempProp( nOpenEdges, 0) ; + + bOptimizedTrap = true ; + return true ; +} + +//---------------------------------------------------- +bool +Pocketing::CalcTrapezoidSpiralLocalFrame( ICurveComposite * pCrvPocket, const Vector3d& vtDir, Frame3d& frLoc) +{ + // cerco i lati paralleli a vtDir + int nBaseId = -1 ; + for ( int i = 0 ; i < pCrvPocket->GetCurveCount() ; i ++) { + Vector3d vtEdge ; + pCrvPocket->GetCurve( i)->GetStartDir( vtEdge) ; + if ( AreSameOrOppositeVectorApprox( vtEdge, vtDir)) { + nBaseId = i ; + break ; + } + } + if ( nBaseId != 0 && nBaseId != 1) + return false ; + + // imposto come lato iniziale per la curva uno dei lati paralleli a vtDir (possibilmente aperto) + int nProp0, nProp2 ; + pCrvPocket->GetCurveTempProp( nBaseId, nProp0) ; + pCrvPocket->GetCurveTempProp( nBaseId + 2, nProp2) ; + if ( ! nProp0 && nProp2) + pCrvPocket->ChangeStartPoint( nBaseId + 2) ; + else + pCrvPocket->ChangeStartPoint( nBaseId) ; + + Point3d ptOrig ; + pCrvPocket->GetStartPoint( ptOrig) ; + Vector3d vtExtr ; + pCrvPocket->GetExtrusion( vtExtr) ; + Vector3d vtX ; + pCrvPocket->GetStartDir( vtX) ; + return frLoc.Set( ptOrig, vtExtr, vtX) ; +} + +//------------------------------------------------------ +bool +Pocketing::CalcTrapezoidSpiralXCoord( const ICurveComposite * pCrvPocket, bool bStart, double dYCoord, double& dXCoord) +{ + int nCrvId = bStart ? 3 : 1 ; + int nProp ; + + // se open + if ( pCrvPocket->GetCurveTempProp( nCrvId, nProp) && nProp) { + Point3d pt1, pt2 ; + pCrvPocket->GetCurve( nCrvId)->GetStartPoint( pt1) ; + pCrvPocket->GetCurve( nCrvId)->GetEndPoint( pt2) ; + if ( bStart) + dXCoord = min( pt1.x, pt2.x) ; + else + dXCoord = max( pt1.x, pt2.x) ; + } + // se closed + else { + double dRad = 0.5 * m_TParams.m_dDiam + GetOffsR() ; + double dVal ; + Vector3d vtRef ; + pCrvPocket->GetCurve( nCrvId)->GetStartDir( vtRef) ; + double dCosAlpha = vtRef * X_AX ; + + if ( dRad * dCosAlpha < dYCoord) { + double dSinAlpha = ( vtRef ^ X_AX).Len() ; + if ( abs( dSinAlpha) < EPS_SMALL) + return false ; + dVal = 1 / dSinAlpha * ( dRad - dYCoord * dCosAlpha) ; + } + else + dVal = sqrt( dRad * dRad - dYCoord * dYCoord) ; + + Point3d ptRef ; + if ( bStart) { + pCrvPocket->GetCurve( nCrvId)->GetEndPoint( ptRef) ; + dXCoord = ptRef.x + dVal ; + } + else { + pCrvPocket->GetCurve( nCrvId)->GetStartPoint( ptRef) ; + dXCoord = ptRef.x - dVal ; + } + } + return true ; +} + +//---------------------------------------------------- +bool +Pocketing::AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite * pCompo, ICurveComposite * pRCrv, const Vector3d& vtTool, double dDepth, + int& nOutsideRaw) +{ + // start point + bool bStartOutside = false ; + ComputeTrapezoidSpiralLeadInLeadOut( pCompo, true, vtTool, dDepth, bStartOutside) ; + // end point + bool bEndOutside = false ; + ComputeTrapezoidSpiralLeadInLeadOut( pCompo, false, vtTool, dDepth, bEndOutside) ; + + // eventuale inversione della curva per partire sempre dall'esterno del grezzo + if ( bEndOutside && ! bStartOutside) + pCompo->Invert() ; + + nOutsideRaw = 0 ; + if ( bStartOutside && bEndOutside) + nOutsideRaw = 2 ; + else if ( bStartOutside || bEndOutside ) { + nOutsideRaw = 1 ; + + // calcolo percorso di ritorno + pRCrv->Clear() ; + Point3d ptS, ptE ; + pCompo->GetStartPoint( ptS) ; + pCompo->GetEndPoint( ptE) ; + PtrOwner pRLine( CreateCurveLine()) ; + pRLine->Set( ptE, ptS) ; + pRCrv->AddCurve( Release( pRLine)) ; + } + + return true ; +} + +//---------------------------------------------------- +bool +Pocketing::ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite * pCompo, bool bLeadIn, const Vector3d& vtTool, double dDepth, bool& bIsOutsideRaw) +{ + Vector3d vtDir ; + Point3d pt ; + if ( bLeadIn) { + pCompo->GetStartPoint( pt) ; + pCompo->GetStartDir( vtDir) ; + } + else { + pCompo->GetEndPoint( pt) ; + pCompo->GetEndDir( vtDir) ; + } + + // recupero info sui lati aperti + int nPropOpen = pCompo->GetTempProp( 0) ; + bool bEdgeOpen = ( nPropOpen & ( bLeadIn ? 8 : 2)) > 0 ; + bool bBaseOpen = ( nPropOpen & 1) > 0 ; + + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + + if ( bEdgeOpen) { + // se lato inclinato è apert tento con prolungamento della curva lungo vtDir + Point3d ptTest ; + if ( bLeadIn) + ptTest = pt - vtDir * ( 0.5 * m_TParams.m_dDiam + dSafeZ) ; + else + ptTest = pt + vtDir * ( 0.5 * m_TParams.m_dDiam + dSafeZ) ; + ptTest += - vtTool * dDepth ; + + double dTestElev ; + // se fuori dal grezzo + if ( ! GetElevation( m_nPhase, ptTest, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dTestElev) || dTestElev < EPS_SMALL) { + if ( bLeadIn) + pCompo->ExtendStartByLen( 0.5 * m_TParams.m_dDiam + dSafeZ) ; + else + pCompo->ExtendEndByLen( 0.5 * m_TParams.m_dDiam + dSafeZ) ; + bIsOutsideRaw = true ; + } + } + + if ( bBaseOpen && ! bIsOutsideRaw) { + // se base è aperta provo a ruotare di 90 gradi + Vector3d vtDirO = vtDir ; + vtDirO.Rotate( Z_AX, ( m_Params.m_bInvert ? -90 : 90)) ; + double dDist ; + GetDistanceFromRawSide( m_nPhase, pt, vtDirO, dDist) ; + if ( dDist < 0.5 * m_TParams.m_dDiam + EPS_SMALL) { + Point3d ptTestO = pt + vtDirO * ( dDist + 0.5 * m_TParams.m_dDiam + dSafeZ) ; + ptTestO += - vtTool * dDepth ; + double dTestElevO ; + // se è fuori dal grezzo uso inizio ruotato + if ( ! GetElevation( m_nPhase, ptTestO, vtTool, 0.5 * m_TParams.m_dDiam, vtTool, dTestElevO) || dTestElevO < EPS_SMALL) { + Point3d ptNewStart = pt + vtDirO * ( dDist + 0.5 * m_TParams.m_dDiam + dSafeZ) ; + pCompo->AddLine( ptNewStart, ! bLeadIn) ; + bIsOutsideRaw = true ; + } + } + } + return true ; +} + //---------------------------------------------------------------------------- bool Pocketing::ComputePolishingPath( ICurveComposite* pMCrv, ICurveComposite* pRCrv, bool bSplitArcs) diff --git a/Pocketing.h b/Pocketing.h index 9cdc481..2263737 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -90,17 +90,24 @@ class Pocketing : public Machining double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; bool AddSpiralIn( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dOkStep, bool bSplitArcs, bool bMidOpen, - const Point3d& ptMidOpen, const Vector3d& vtMidOut) ; + const Point3d& ptMidOpen, const Vector3d& vtMidOut, int nPathId) ; bool AddSpiralOut( const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, double dOkStep, bool bSplitArcs) ; - bool CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, - ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; + double dDepth, double dElev, double dOkStep, bool bSplitArcs, int nPathId) ; + bool CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs, + ICurveComposite* pMCrv, ICurveComposite* pRCrv, int nPathId, bool& bOptimizedTrap) ; bool CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ICurve* pCrvBound, ICurveComposite* pCrvLink) ; bool CalcBoundedLinkWithBiArcs( const Point3d& ptStart, const Vector3d& vtStart, const Point3d& ptEnd, const Vector3d& vtEnd, const ICurve* pCrvBound, ICurveComposite* pCrvLink) ; bool CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double dOutRad, double dIntRad, bool bSplitArcs, ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; + bool CalcTrapezoidSpiral( ICurveComposite * pCrvPocket, const Vector3d& vtDir, double dPocketSize, + ICurveComposite * pMCrv, ICurveComposite * pRCrv, bool& bOptimizedTrap) ; + bool CalcTrapezoidSpiralLocalFrame( ICurveComposite * pCrvPocket, const Vector3d& vtDir, Frame3d& frLoc) ; + bool CalcTrapezoidSpiralXCoord( const ICurveComposite * pCrvPocket, bool bStart, double dYCoord, double& dXCoord) ; + bool AdjustTrapezoidSpiralForLeadInLeadOut( ICurveComposite * pCompo, ICurveComposite * pRCrv, const Vector3d& vtTool, + double dDepth, int& nOutsideRaw) ; + bool ComputeTrapezoidSpiralLeadInLeadOut( ICurveComposite * pCompo, bool bLeadIn, const Vector3d& vtTool, double dDepth, bool& bIsOutsideRaw) ; bool ComputePolishingPath( ICurveComposite* pMCrv, ICurveComposite* pRCrv, bool bSplitArcs) ; bool AddEpicycles( ICurveComposite * pCompo, ICurveComposite * pCrv, ICurveComposite * pCrvBound = nullptr) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ,