From 846412f2561f2f7002d349e97bb7f0b12663abaa Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Fri, 12 Jul 2024 08:47:20 +0200 Subject: [PATCH] =?UTF-8?q?EgtMachKerenel=20:=20-=20ora=20SurfFinishing=20?= =?UTF-8?q?non=20calcola=20pi=C3=B9=20le=20svuotature=20ma=20usa=20CalcPoc?= =?UTF-8?q?keting.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SurfFinishing.cpp | 1202 ++++++++++++++------------------------------- SurfFinishing.h | 14 +- 2 files changed, 364 insertions(+), 852 deletions(-) diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index e791846..9561562 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -1102,7 +1102,7 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) m_pGeomDB->EmptyGroup( nTempId) ; // in ogni caso lo dichiaro temporaneo e non visibile m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ; - //m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; + m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; // verifico sia una curva chiusa (deve delimitare l'area da svuotare) int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; @@ -1159,8 +1159,8 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) return false ; } - // recupero flag di saltare parti a massimo affondamento - bool bSkipMaxDown = false ; + // recupero flag per saltare parti a massimo affondamento + bool bSkipMaxDown = true ; GetValInNotes( m_Params.m_sUserNotes, "SkipMaxDown", bSkipMaxDown) ; // recupero nome del path @@ -1271,20 +1271,19 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) PtrOwner pSfrSil( SfrMaker.GetSurf()) ; if ( ! IsNull( pSfrSil)) { pSfrSil->ToGlob( frSurf) ; - const double EXTRA_OFFS = 2 ; double dPockRadOffs = m_TParams.m_dDiam - m_Params.m_dSideStep - m_Params.m_dOverlap ; pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ; // offset radiale sulla Silhouette } // intersezione tra contorno e regione pSfrCnt->Intersect( *pSfrSil) ; - if ( pSfrCnt->IsValid() && pSfrCnt->GetChunkCount() > 0) { - PtrOwner pCont( ConvertCurveToComposite( pSfrCnt->GetLoop( 0, 0))) ; - if ( ! IsNull( pCont)) { - int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pCont)) ; - if ( nNewId != GDB_ID_NULL) - pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nNewId)) ; - } - } + //if ( pSfrCnt->IsValid() && pSfrCnt->GetChunkCount() > 0) { + // PtrOwner pCont( ConvertCurveToComposite( pSfrCnt->GetLoop( 0, 0))) ; + // if ( ! IsNull( pCont)) { + // int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pCont)) ; + // if ( nNewId != GDB_ID_NULL) + // pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nNewId)) ; + // } + //} } // assegno il vettore estrazione al gruppo del percorso @@ -1298,19 +1297,19 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) double dElev = dDepth ; switch ( m_Params.m_nSubType) { case SURFFIN_SUB_ZIGZAG : - if ( ! AddZigZag( pCAvTlStm, frSurf, pCompo, vtTool, vtTool, dDepth, dElev, bSplitArcs, false)) + if ( ! AddZigZag( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs)) return false ; break ; case SURFFIN_SUB_ONEWAY : - if ( ! AddOneWay( pCAvTlStm, frSurf, pCompo, vtTool, vtTool, dDepth, dElev, bSplitArcs, false)) + if ( ! AddOneWay( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs)) return false ; break ; case SURFFIN_SUB_SPIRALIN : - if ( ! AddSpiral( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs, true, false)) + if ( ! AddSpiral( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs, true)) return false ; break ; case SURFFIN_SUB_SPIRALOUT : - if ( ! AddSpiral( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs, false, false)) + if ( ! AddSpiral( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs, false)) return false ; break ; } @@ -1373,481 +1372,200 @@ SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId) const //---------------------------------------------------------------------------- bool -SurfFinishing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs, bool bSkipMaxDown) +SurfFinishing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) { // recupero distanze di sicurezza double dSafeZ = GetSafeZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - // calcolo curva offsettata del raggio utensile - double dOffs = m_Params.m_dOverlap - 0.5 * m_TParams.m_dDiam ; - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCompo, dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 3109, "Error in SurfFinishing : Offset not computable") ; + // calcolo lo zig-zag + double dPockRad = m_Params.m_dSideStep ; + double dPockRadOffs = m_TParams.m_dDiam / 2 - m_Params.m_dSideStep - m_Params.m_dOverlap ; + ICRVCOMPOPOVECTOR vpCrvs ; + if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, + POCKET_ZIGZAG, false, false, nullptr, vpCrvs)) { + m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } + // determino il riferimento di base della svuotatura + Frame3d frPocket ; + Point3d ptCen ; pSfrPock->GetCentroid( ptCen) ; + frPocket.Set( ptCen, vtTool) ; + // ciclo sulle curve risultanti bool bStart = true ; - while ( OffsCrv.GetCurveCount() > 0) { - // recupero la prima curva di offset - PtrOwner pOffs ; - if ( ! pOffs.Set( ConvertCurveToComposite( OffsCrv.GetLongerCurve()))) { - m_pMchMgr->SetLastError( 3110, "Error in SurfFinishing : Toolpath not computable") ; - return false ; + double dProgCoeff = 1. / max( int( vpCrvs.size()), 1) ; + for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { + PtrOwner pMCrv( Release( vpCrvs[k])) ; + pMCrv->ToLoc( frPocket) ; + // li correggo per non interferire con le superfici + if ( pCAvTlStm != nullptr) { + // approssimo la curva con una polilinea + PolyLine PL ; + if ( ! pMCrv->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) + return false ; + // eventuale aggiunta di punti per garantire max distanza + const double MIN_DIST = 1. ; + const double MAX_DIST = 50. ; + double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; + if ( ! PL.AdjustForMaxSegmentLen( dDist)) + return false ; + // porto nel riferimento delle superfici + PL.LocToLoc( frPocket, frSurf) ; + // porto i dati geometrici in locale alle superfici + Vector3d vtAxL = vtTool ; + vtAxL.ToLoc( frSurf) ; + Vector3d vtMoveL = vtAxL ; + // traslo della lunghezza utensile diminuita dell'affondamento + PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; + // eseguo CAv + if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( k + 1) * dProgCoeff)) + return false ; + // contro-traslo della lunghezza utensile + PL.Translate( - vtAxL * m_TParams.m_dLen) ; + // riporto la polilinea nel riferimento della curva + PL.LocToLoc( frSurf, frPocket) ; + // elimino i punti allineati + PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; + // creo una curva composita a partire dalla polilinea + PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) + return false ; + // sostituisco la vecchia curva con la nuova + pMCrv.Set( pCompo) ; } - // determino il riferimento di base e il box della svuotatura - Frame3d frPocket ; - Point3d ptCen ; pCompo->GetCentroid( ptCen) ; - frPocket.Set( ptCen, vtExtr) ; - frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; - pOffs->ToLoc( frPocket) ; - // calcolo i percorsi di svuotatura - ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcZigZag( pOffs, vpCrvs)) - return false ; - // ciclo sui percorsi - for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { - // li correggo per non interferire con le superfici - if ( pCAvTlStm != nullptr) { - // approssimo la curva con una polilinea - PolyLine PL ; - if ( ! vpCrvs[k]->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) - return false ; - // eventuale aggiunta di punti per garantire max distanza - const double MIN_DIST = 1. ; - const double MAX_DIST = 50. ; - double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; - if ( ! PL.AdjustForMaxSegmentLen( dDist)) - return false ; - // porto nel riferimento delle superfici - PL.LocToLoc( frPocket, frSurf) ; - // porto i dati geometrici in locale alle superfici - Vector3d vtAxL = vtTool ; - vtAxL.ToLoc( frSurf) ; - Vector3d vtMoveL = vtAxL ; - // traslo della lunghezza utensile diminuita dell'affondamento - PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; - // eseguo CAv - if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox)) - return false ; - // contro-traslo della lunghezza utensile - PL.Translate( - vtAxL * m_TParams.m_dLen) ; - // riporto la polilinea nel riferimento della curva - PL.LocToLoc( frSurf, frPocket) ; - // elimino i punti allineati - PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; - // se richiesto, elimino i punti al massimo affondamento - if ( bSkipMaxDown) { - PNTULIST& vPntU = PL.GetUPointList() ; - bool bPrevDwn = true ; - Point3d ptPrev = P_INVALID ; - auto currPU = vPntU.begin() ; - while ( currPU != vPntU.end()) { - auto nextPU = next( currPU) ; - bool bNext = ( nextPU != vPntU.end()) ; - bool bNextDown = ( bNext ? nextPU->second < m_Params.m_dApprox : true) ; - // punto corrente è al minimo - if ( currPU->second < m_Params.m_dApprox) { - // se precedente e successivo al minimo, cancello e basta - if ( bPrevDwn && bNextDown) { - if ( ! ptPrev.IsValid() || abs( currPU->first.y - ptPrev.y) > 10 * EPS_SMALL) - ptPrev = currPU->first ; - currPU = vPntU.erase( currPU) ; - bPrevDwn = true ; - } - // se precedente ok e successivo al minimo, aggiungo opportuno movimento di uscita - else if ( ! bPrevDwn && bNextDown && bNext) { - Vector3d vtDir = nextPU->first - currPU->first ; - double dMove = vtDir.Len() ; - if ( dMove > 100 * EPS_SMALL) { - vtDir /= dMove ; - dMove = min( dMove, 2.) ; - Point3d ptNew = currPU->first + vtDir * dMove ; - ptPrev = ptNew ; - currPU = next( vPntU.insert( nextPU, { ptNew, 0})) ; - bPrevDwn = true ; - } - else { - ptPrev = currPU->first ; - currPU = nextPU ; - bPrevDwn = false ; - } - } - // se precedente al minimo e successivo ok, aggiungo opportuno movimento di ingresso - else if ( bPrevDwn && ptPrev.IsValid() && ! bNextDown) { - Vector3d vtDir = currPU->first - ptPrev ; - double dMove = vtDir.Len() ; - if ( dMove > 9 * EPS_SMALL) { - vtDir /= dMove ; - dMove = min( dMove, 2.) ; - Point3d ptNew = currPU->first - vtDir * dMove ; - vPntU.insert( currPU, { ptNew, 0}) ; - ptPrev = currPU->first ; - currPU = nextPU ; - } - else { - ptPrev = currPU->first ; - currPU = nextPU ; - } - bPrevDwn = true ; - } - // altrimenti va tenuto - else { - ptPrev = currPU->first ; - currPU = nextPU ; - bPrevDwn = true ; - } - } - // punto corrente sulla superficie - else { - ptPrev = currPU->first ; - currPU = nextPU ; - bPrevDwn = false ; - } - } + // 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( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + pCurve->ToGlob( frPocket) ; + // se prima entità + if ( i == 0 ) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // vettore tangente iniziale non deve salire rispetto a estrusione (poi si prende opposto) + double dStartOnExtr = vtStart * vtTool ; + if ( dStartOnExtr > 0) { + vtStart -= dStartOnExtr * vtTool ; + vtStart.Normalize() ; } - // creo una curva composita a partire dalla polilinea - PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; - if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) - return false ; - // sostituisco la vecchia curva con la nuova - vpCrvs[k].Set( pCompo) ; - } - // ciclo sulle curve elementari - int nMaxInd = vpCrvs[k]->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = vpCrvs[k]->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) - return false ; - pCurve->ToGlob( frPocket) ; - // se prima entità - if ( i == 0 ) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // vettore tangente iniziale non deve salire rispetto a estrusione (poi si prende opposto) - double dStartOnExtr = vtStart * vtExtr ; - if ( dStartOnExtr > 0) { - vtStart -= dStartOnExtr * vtExtr ; - vtStart.Normalize() ; - } - // determino normale della superficie sul punto iniziale - Vector3d vtNorm ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtExtr, vtNorm)) { - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtExtr, vtNorm)) - vtNorm = V_NULL ; - } - // determino inizio attacco - Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, vtNorm, ptP1)) - return false ; - // eventuale correzione inizio attacco per evitare interferenze - if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptStart, ptP1, vtTool, ptP1)) - return false ; - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dElev ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se inizio, approccio globale al punto iniziale - if ( bStart) { - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { - m_pMchMgr->SetLastError( 3111, "Error in SurfFinishing : Approach not computable") ; - return false ; - } - bStart = false ; - } - // altrimenti, approccio di collegamento - else { - if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { - m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; - return false ; - } - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bSplitArcs)) { - m_pMchMgr->SetLastError( 3113, "Error in SurfFinishing : LeadIn not computable") ; - return false ; - } - } - // elaborazioni sulla curva corrente (sempre un segmento di retta) - ICurveLine* pLine = GetCurveLine( pCurve) ; - if ( pLine == nullptr) - return false ; - Point3d ptP3 = pLine->GetEnd() ; - Vector3d vtMove ; pLine->GetStartDir( vtMove) ; - SetFeed( GetRightFeed( vtMove, vtTool)) ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) - return false ; - // se ultima entità - if ( i == nMaxInd) { - // dati fine entità + // determino normale della superficie sul punto iniziale + Vector3d vtNorm ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtTool, vtNorm)) { Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // vettore tangente finale non deve scendere rispetto a estrusione - double dEndOnExtr = vtEnd * vtExtr ; - if ( dEndOnExtr < 0) { - vtEnd -= dEndOnExtr * vtExtr ; - vtEnd.Normalize() ; - } - // determino normale della superficie sul punto finale - Vector3d vtNorm ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtExtr, vtNorm)) { - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtExtr, vtNorm)) - vtNorm = V_NULL ; - } - // determino fine uscita - Point3d ptP1 ; - if ( ! CalcLeadOutEnd( ptEnd, vtEnd, vtExtr, vtNorm, ptP1)) - return false ; - // eventuale correzione fine uscita per evitare interferenze - if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptEnd, ptP1, vtTool, ptP1)) - return false ; - // aggiungo uscita - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, ptP1, vtExtr, bSplitArcs)) { - m_pMchMgr->SetLastError( 3114, "Error in SurfFinishing : LeadOut not computable") ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtTool, vtNorm)) + vtNorm = V_NULL ; + } + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, vtNorm, ptP1)) + return false ; + // eventuale correzione inizio attacco per evitare interferenze + if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptStart, ptP1, vtTool, ptP1)) + return false ; + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dElev ; + dStElev -= ( ptP1 - ptStart) * vtTool ; + // se inizio, approccio globale al punto iniziale + if ( bStart) { + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { + m_pMchMgr->SetLastError( 3111, "Error in SurfFinishing : Approach not computable") ; return false ; } - // determino elevazione su fine uscita - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) - dEndElev = dElev ; - dEndElev -= ( ptP1 - ptEnd) * vtExtr ; - // se non è ultimo tratto, aggiungo retrazione di collegamento - if ( k < int( vpCrvs.size()) - 1) { - if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; - return false ; - } - } - // altrimenti aggiungo retrazione finale - else { - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 3115, "Error in SurfFinishing : Retract not computable") ; - return false ; - } - } - } - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -SurfFinishing::CalcZigZag( const ICurveComposite* pOffs, - ICRVCOMPOPOVECTOR& vpCrvs) -{ - // ingombro del contorno offsettato - BBox3d b3Pocket ; - pOffs->GetLocalBBox( b3Pocket) ; - Point3d ptMin ; double dDimX, dDimY, dDimZ ; - b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; - - // lunghezza del contorno offsettato - double dLen ; pOffs->GetLength( dLen) ; - - // passi in Y - int nYStep = static_cast( ceil( ( dDimY - 20 * EPS_SMALL) / GetSideStep())) ; - double dYStep = ( nYStep > 0 ? ( dDimY - 20 * EPS_SMALL) / nYStep : 0) ; - - // tratto valido - struct Section { - bool bActive ; - Point3d ptS ; - Point3d ptE ; - double dOs ; - double dOe ; - } ; - // raccolta di tratti - typedef vector> VECVECSECT ; - - VECVECSECT vvSec ; - vvSec.resize( nYStep + 1) ; - - // calcolo le linee di svuotatura - int nCount = 0 ; - for ( int i = 0 ; i <= nYStep ; ++ i) { - // determino senso - bool bPlus = (( i % 2) == 0) ; - // definisco la linea - PtrOwner pLine( CreateCurveLine()) ; - const double EXP_LEN = 1.0 ; - Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + 10 * EPS_SMALL + i * dYStep, ptMin.z + dDimZ) ; - if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) { - m_pMchMgr->SetLastError( 3110, "Error in SurfFinishing : Toolpath not computable") ; - return false ; - } - // calcolo la classificazione della curva rispetto al contorno esterno offsettato - IntersCurveCurve intCC( *pLine, *pOffs) ; - CRVCVECTOR ccClass ; - if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) { - m_pMchMgr->SetLastError( 3110, "Error in SurfFinishing : Toolpath not computable") ; - return false ; - } - // determino gli intervalli di curva da conservare - Intervals inOk ; - for ( auto& ccOne : ccClass) { - if ( ccOne.nClass == CRVC_IN || ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M) - inOk.Add( ccOne.dParS, ccOne.dParE) ; - } - // inserisco i tratti validi (secondo X+ i pari, secondo X- i dispari) - double dParS, dParE ; - bool bFound = ( bPlus ? inOk.GetFirst( dParS, dParE) : inOk.GetLast( dParE, dParS)) ; - while ( bFound) { - // determino i dati della sezione - Section Sect ; - Sect.bActive = true ; - pLine->GetPointD1D2( dParS, ICurve::FROM_PLUS, Sect.ptS) ; - pLine->GetPointD1D2( dParE, ICurve::FROM_MINUS, Sect.ptE) ; - pOffs->GetParamAtPoint( Sect.ptS, Sect.dOs, 10 * EPS_SMALL) ; - pOffs->GetParamAtPoint( Sect.ptE, Sect.dOe, 10 * EPS_SMALL) ; - // inserisco nel contenitore - vvSec[i].emplace_back( Sect) ; - ++ nCount ; - // recupero successivo intervallo - bFound = ( bPlus ? inOk.GetNext( dParS, dParE) : inOk.GetPrev( dParE, dParS)) ; - } - } - - // dominio del contorno - double dUmin, dUmax ; - pOffs->GetDomain( dUmin, dUmax) ; - double dUspan = dUmax - dUmin ; - - // creo i percorsi di svuotatura - vpCrvs.reserve( nCount) ; - int nI = -1, nJ = -1 ; - while ( true) { - // se sezione non valida - if ( nI < 0 || nJ < 0) { - // ricerco la prima valida - for ( int k = 0 ; k < int( vvSec.size()) && nI < 0 ; ++ k) { - for ( int l = 0 ; l < int( vvSec[k].size()) && nJ < 0 ; ++ l) { - if ( vvSec[k][l].bActive) { - nI = k ; - nJ = l ; - } - } - } - // se trovata, creo nuova curva composita - if ( nI >= 0 && nJ >= 0) { - // creo la curva - vpCrvs.emplace_back( CreateCurveComposite()) ; - // aggiungo punto iniziale - vpCrvs.back()->AddPoint( vvSec[nI][nJ].ptS) ; - } - // altrimenti, esco - else - break ; - } - // determino senso - bool bPlus = (( nI % 2) == 0) ; - // aggiungo la sezione alla curva - Section& Sec = vvSec[nI][nJ] ; - Sec.bActive = false ; - vpCrvs.back()->AddLine( vvSec[nI][nJ].ptE) ; - // cerco nella stessa fila o in quella successiva sezione successiva raccordabile tramite il contorno - double dUstart = Sec.dOe ; - double dUref = ( bPlus ? INFINITO : - INFINITO) ; - int nNextI = -1 ; - int nNextJ = -1 ; - int li = nJ + 1 ; - for ( int k = nI ; k <= nI + 1 && k < int( vvSec.size()) ; ++ k) { - for ( int l = li ; l < int( vvSec[k].size()) ; ++ l) { - if ( ! vvSec[k][l].bActive) - continue ; - double dU = vvSec[k][l].dOs ; - if ( bPlus) { - if ( dU < dUstart) - dU += dUspan ; - if ( dU < dUref) { - dUref = dU ; - nNextI = k ; - nNextJ = l ; - } + bStart = false ; } + // altrimenti, approccio di collegamento else { - if ( dU > dUstart) - dU -= dUspan ; - if ( dU > dUref) { - dUref = dU ; - nNextI = k ; - nNextJ = l ; + if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { + m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; + return false ; + } + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, bSplitArcs)) { + m_pMchMgr->SetLastError( 3113, "Error in SurfFinishing : LeadIn not computable") ; + return false ; + } + } + // elaborazioni sulla curva corrente (sempre un segmento di retta) + ICurveLine* pLine = GetCurveLine( pCurve) ; + if ( pLine == nullptr) + return false ; + Point3d ptP3 = pLine->GetEnd() ; + Vector3d vtMove ; pLine->GetStartDir( vtMove) ; + SetFeed( GetRightFeed( vtMove, vtTool)) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + // se ultima entità + if ( i == nMaxInd) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // vettore tangente finale non deve scendere rispetto a estrusione + double dEndOnExtr = vtEnd * vtTool ; + if ( dEndOnExtr < 0) { + vtEnd -= dEndOnExtr * vtTool ; + vtEnd.Normalize() ; + } + // determino normale della superficie sul punto finale + Vector3d vtNorm ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtTool, vtNorm)) { + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtTool, vtNorm)) + vtNorm = V_NULL ; + } + // determino fine uscita + Point3d ptP1 ; + if ( ! CalcLeadOutEnd( ptEnd, vtEnd, vtTool, vtNorm, ptP1)) + return false ; + // eventuale correzione fine uscita per evitare interferenze + if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptEnd, ptP1, vtTool, ptP1)) + return false ; + // aggiungo uscita + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, ptP1, vtTool, bSplitArcs)) { + m_pMchMgr->SetLastError( 3114, "Error in SurfFinishing : LeadOut not computable") ; + return false ; + } + // determino elevazione su fine uscita + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + dEndElev = dElev ; + dEndElev -= ( ptP1 - ptEnd) * vtTool ; + // se non è ultimo tratto, aggiungo retrazione di collegamento + if ( k < int( vpCrvs.size()) - 1) { + if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; + return false ; + } + } + // altrimenti aggiungo retrazione finale + else { + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 3115, "Error in SurfFinishing : Retract not computable") ; + return false ; } } } - li = 0 ; } - // se trovato, aggiungo il tratto di contorno e continuo - if ( nNextI != -1) { - PtrOwner pCopy ; - if ( bPlus) { - if ( dUref > dUmax) - dUref -= dUspan ; - pCopy.Set( pOffs->CopyParamRange( dUstart, dUref)) ; - if ( ! IsNull( pCopy)) { - double dCLen ; pCopy->GetLength( dCLen) ; - if ( dCLen > 0.5 * dLen) { - pCopy.Set( pOffs->CopyParamRange( dUref, dUstart)) ; - if ( ! IsNull( pCopy)) - pCopy->Invert() ; - } - } - } - else { - if ( dUref < dUmin) - dUref += dUspan ; - pCopy.Set( pOffs->CopyParamRange( dUref, dUstart)) ; - if ( ! IsNull( pCopy)) { - pCopy->Invert() ; - double dCLen ; pCopy->GetLength( dCLen) ; - if ( dCLen > 0.5 * dLen) - pCopy.Set( pOffs->CopyParamRange( dUstart, dUref)) ; - } - } - BBox3d b3Copy ; - if ( ! IsNull( pCopy)) - pCopy->GetLocalBBox( b3Copy) ; - if ( ! b3Copy.IsEmpty() && ( b3Copy.GetMax().y - b3Copy.GetMin().y) < dYStep + 10 * EPS_SMALL) { - vpCrvs.back()->AddCurve( Release( pCopy)) ; - nI = nNextI ; - nJ = nNextJ ; - } - else { - nI = -1 ; - nJ = -1 ; - } - } - else { - nI = -1 ; - nJ = -1 ; - } - } - - // se richiesta percorrenza invertita - if ( m_Params.m_bInvert) { - for ( auto& pCompo : vpCrvs) - pCompo->Invert() ; } return true ; @@ -1855,280 +1573,196 @@ SurfFinishing::CalcZigZag( const ICurveComposite* pOffs, //---------------------------------------------------------------------------- bool -SurfFinishing::AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs, bool bSkipMaxDown) +SurfFinishing::AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) { // recupero distanze di sicurezza double dSafeZ = GetSafeZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - // calcolo curva offsettata del raggio utensile - double dOffs = m_Params.m_dOverlap - 0.5 * m_TParams.m_dDiam ; - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCompo, dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 3109, "Error in SurfFinishing : Offset not computable") ; + // calcolo lo one-way + double dPockRad = m_Params.m_dSideStep ; + double dPockRadOffs = m_TParams.m_dDiam / 2 - m_Params.m_dSideStep - m_Params.m_dOverlap ; + ICRVCOMPOPOVECTOR vpCrvs ; + if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, + POCKET_ONEWAY, false, false, nullptr, vpCrvs)) { + m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } + // determino il riferimento di base della svuotatura + Frame3d frPocket ; + Point3d ptCen ; pSfrPock->GetCentroid( ptCen) ; + frPocket.Set( ptCen, vtTool) ; + // ciclo sulle curve risultanti bool bStart = true ; - while ( OffsCrv.GetCurveCount() > 0) { - // recupero la prima curva di offset - PtrOwner pOffs ; - if ( ! pOffs.Set( ConvertCurveToComposite( OffsCrv.GetLongerCurve()))) { - m_pMchMgr->SetLastError( 3110, "Error in SurfFinishing : Toolpath not computable") ; - return false ; + double dProgCoeff = 1. / max( int( vpCrvs.size()), 1) ; + for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { + PtrOwner pMCrv( Release( vpCrvs[k])) ; + pMCrv->ToLoc( frPocket) ; + // li correggo per non interferire con le superfici + if ( pCAvTlStm != nullptr) { + // approssimo la curva con una polilinea + PolyLine PL ; + if ( ! pMCrv->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) + return false ; + // eventuale aggiunta di punti per garantire max distanza + const double MIN_DIST = 1. ; + const double MAX_DIST = 50. ; + double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; + if ( ! PL.AdjustForMaxSegmentLen( dDist)) + return false ; + // porto nel riferimento delle superfici + PL.LocToLoc( frPocket, frSurf) ; + // porto i dati geometrici in locale alle superfici + Vector3d vtAxL = vtTool ; + vtAxL.ToLoc( frSurf) ; + Vector3d vtMoveL = vtAxL ; + // traslo della lunghezza utensile diminuita dell'affondamento + PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; + // eseguo CAv + if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( k + 1) * dProgCoeff)) + return false ; + // contro-traslo della lunghezza utensile + PL.Translate( - vtAxL * m_TParams.m_dLen) ; + // riporto la polilinea nel riferimento della curva + PL.LocToLoc( frSurf, frPocket) ; + // elimino i punti allineati + PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; + // creo una curva composita a partire dalla polilinea + PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) + return false ; + // sostituisco la vecchia curva con la nuova + pMCrv.Set( pCompo) ; } - // determino il riferimento di base e il box della svuotatura - Frame3d frPocket ; - Point3d ptCen ; pCompo->GetCentroid( ptCen) ; - frPocket.Set( ptCen, vtExtr) ; - frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; - pOffs->ToLoc( frPocket) ; - // calcolo i percorsi di svuotatura - ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcOneWay( pOffs, vpCrvs)) - return false ; - // ciclo sui percorsi - double dProgCoeff = 1. / max( int( vpCrvs.size()), 1) ; - for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { - // li correggo per non interferire con le superfici - if ( pCAvTlStm != nullptr) { - // approssimo la curva con una polilinea - PolyLine PL ; - if ( ! vpCrvs[k]->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) - return false ; - // eventuale aggiunta di punti per garantire max distanza - const double MIN_DIST = 1. ; - const double MAX_DIST = 50. ; - double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; - if ( ! PL.AdjustForMaxSegmentLen( dDist)) - return false ; - // porto nel riferimento delle superfici - PL.LocToLoc( frPocket, frSurf) ; - // porto i dati geometrici in locale alle superfici - Vector3d vtAxL = vtTool ; - vtAxL.ToLoc( frSurf) ; - Vector3d vtMoveL = vtAxL ; - // traslo della lunghezza utensile diminuita dell'affondamento - PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; - // eseguo CAv - if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( k + 1) * dProgCoeff)) - return false ; - // contro-traslo della lunghezza utensile - PL.Translate( - vtAxL * m_TParams.m_dLen) ; - // riporto la polilinea nel riferimento della curva - PL.LocToLoc( frSurf, frPocket) ; - // elimino i punti allineati - PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; - // se richiesto, elimino i punti al massimo affondamento - if ( bSkipMaxDown) { - PNTULIST& vPntU = PL.GetUPointList() ; - bool bPrevDwn = true ; - Point3d ptPrev = P_INVALID ; - auto currPU = vPntU.begin() ; - while ( currPU != vPntU.end()) { - auto nextPU = next( currPU) ; - bool bNext = ( nextPU != vPntU.end()) ; - bool bNextDown = ( bNext ? nextPU->second < m_Params.m_dApprox : true) ; - // punto corrente è al minimo - if ( currPU->second < m_Params.m_dApprox) { - // se precedente e successivo al minimo, cancello e basta - if ( bPrevDwn && bNextDown) { - if ( ! ptPrev.IsValid() || abs( currPU->first.y - ptPrev.y) > 10 * EPS_SMALL) - ptPrev = currPU->first ; - currPU = vPntU.erase( currPU) ; - bPrevDwn = true ; - } - // se precedente ok e successivo al minimo, aggiungo opportuno movimento di uscita - else if ( ! bPrevDwn && bNextDown && bNext) { - Vector3d vtDir = nextPU->first - currPU->first ; - double dMove = vtDir.Len() ; - if ( dMove > 100 * EPS_SMALL) { - vtDir /= dMove ; - dMove = min( dMove, 2.) ; - Point3d ptNew = currPU->first + vtDir * dMove ; - ptPrev = ptNew ; - currPU = next( vPntU.insert( nextPU, { ptNew, 0})) ; - bPrevDwn = true ; - } - else { - ptPrev = currPU->first ; - currPU = nextPU ; - bPrevDwn = false ; - } - } - // se precedente al minimo e successivo ok, aggiungo opportuno movimento di ingresso - else if ( bPrevDwn && ptPrev.IsValid() && ! bNextDown) { - Vector3d vtDir = currPU->first - ptPrev ; - double dMove = vtDir.Len() ; - if ( dMove > 9 * EPS_SMALL) { - vtDir /= dMove ; - dMove = min( dMove, 2.) ; - Point3d ptNew = currPU->first - vtDir * dMove ; - vPntU.insert( currPU, { ptNew, 0}) ; - ptPrev = currPU->first ; - currPU = nextPU ; - } - else { - ptPrev = currPU->first ; - currPU = nextPU ; - } - bPrevDwn = true ; - } - // altrimenti va tenuto - else { - ptPrev = currPU->first ; - currPU = nextPU ; - bPrevDwn = true ; - } - } - // punto corrente sulla superficie - else { - ptPrev = currPU->first ; - currPU = nextPU ; - bPrevDwn = false ; - } - } - // se eliminati tutti i punti passo oltre - if ( PL.GetLineNbr() == 0) - continue ; + // 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( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + pCurve->ToGlob( frPocket) ; + // se prima entità + if ( i == 0 ) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // vettore tangente iniziale non deve salire rispetto a estrusione (poi si prende opposto) + double dStartOnExtr = vtStart * vtTool ; + if ( dStartOnExtr > 0) { + vtStart -= dStartOnExtr * vtTool ; + vtStart.Normalize() ; } - // creo una curva composita a partire dalla polilinea - PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; - if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) - return false ; - // sostituisco la vecchia curva con la nuova - vpCrvs[k].Set( pCompo) ; - } - // ciclo sulle curve elementari - int nMaxInd = vpCrvs[k]->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = vpCrvs[k]->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) - return false ; - pCurve->ToGlob( frPocket) ; - // se prima entità - if ( i == 0 ) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // vettore tangente iniziale non deve salire rispetto a estrusione (poi si prende opposto) - double dStartOnExtr = vtStart * vtExtr ; - if ( dStartOnExtr > 0) { - vtStart -= dStartOnExtr * vtExtr ; - vtStart.Normalize() ; - } - // determino normale della superficie sul punto iniziale - Vector3d vtNorm ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtExtr, vtNorm)) { - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtExtr, vtNorm)) - vtNorm = V_NULL ; - } - // determino inizio attacco - Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, vtNorm, ptP1)) - return false ; - // eventuale correzione inizio attacco per evitare interferenze - if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptStart, ptP1, vtTool, ptP1)) - return false ; - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dElev ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se inizio, approccio globale al punto iniziale - if ( bStart) { - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { - m_pMchMgr->SetLastError( 3111, "Error in SurfFinishing : Approach not computable") ; - return false ; - } - bStart = false ; - } - // altrimenti, approccio di collegamento - else { - if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { - m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; - return false ; - } - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bSplitArcs)) { - m_pMchMgr->SetLastError( 3113, "Error in SurfFinishing : LeadIn not computable") ; - return false ; - } - } - // elaborazioni sulla curva corrente (sempre un segmento di retta) - ICurveLine* pLine = GetCurveLine( pCurve) ; - if ( pLine == nullptr) - return false ; - Point3d ptP3 = pLine->GetEnd() ; - Vector3d vtMove ; pLine->GetStartDir( vtMove) ; - SetFeed( GetRightFeed( vtMove, vtTool)) ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) - return false ; - // se ultima entità - if ( i == nMaxInd) { - // dati fine entità + // determino normale della superficie sul punto iniziale + Vector3d vtNorm ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtTool, vtNorm)) { Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // vettore tangente finale non deve scendere rispetto a estrusione - double dEndOnExtr = vtEnd * vtExtr ; - if ( dEndOnExtr < 0) { - vtEnd -= dEndOnExtr * vtExtr ; - vtEnd.Normalize() ; - } - // determino normale della superficie sul punto finale - Vector3d vtNorm ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtExtr, vtNorm)) { - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtExtr, vtNorm)) - vtNorm = V_NULL ; - } - // determino fine uscita - Point3d ptP1 ; - if ( ! CalcLeadOutEnd( ptEnd, vtEnd, vtExtr, vtNorm, ptP1)) - return false ; - // eventuale correzione fine uscita per evitare interferenze - if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptEnd, ptP1, vtTool, ptP1)) - return false ; - // aggiungo uscita - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, ptP1, vtExtr, bSplitArcs)) { - m_pMchMgr->SetLastError( 3114, "Error in SurfFinishing : LeadOut not computable") ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtTool, vtNorm)) + vtNorm = V_NULL ; + } + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, vtNorm, ptP1)) + return false ; + // eventuale correzione inizio attacco per evitare interferenze + if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptStart, ptP1, vtTool, ptP1)) + return false ; + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dElev ; + dStElev -= ( ptP1 - ptStart) * vtTool ; + // se inizio, approccio globale al punto iniziale + if ( bStart) { + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { + m_pMchMgr->SetLastError( 3111, "Error in SurfFinishing : Approach not computable") ; return false ; } - // determino elevazione su fine uscita - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) - dEndElev = dElev ; - dEndElev -= ( ptP1 - ptEnd) * vtExtr ; - // se non è ultimo tratto, aggiungo retrazione di collegamento - if ( k < int( vpCrvs.size()) - 1) { - if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; - return false ; - } + bStart = false ; + } + // altrimenti, approccio di collegamento + else { + if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { + m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; + return false ; } - // altrimenti aggiungo retrazione finale - else { - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 3115, "Error in SurfFinishing : Retract not computable") ; - return false ; - } + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, bSplitArcs)) { + m_pMchMgr->SetLastError( 3113, "Error in SurfFinishing : LeadIn not computable") ; + return false ; + } + } + // elaborazioni sulla curva corrente (sempre un segmento di retta) + ICurveLine* pLine = GetCurveLine( pCurve) ; + if ( pLine == nullptr) + return false ; + Point3d ptP3 = pLine->GetEnd() ; + Vector3d vtMove ; pLine->GetStartDir( vtMove) ; + SetFeed( GetRightFeed( vtMove, vtTool)) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + // se ultima entità + if ( i == nMaxInd) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // vettore tangente finale non deve scendere rispetto a estrusione + double dEndOnExtr = vtEnd * vtTool ; + if ( dEndOnExtr < 0) { + vtEnd -= dEndOnExtr * vtTool ; + vtEnd.Normalize() ; + } + // determino normale della superficie sul punto finale + Vector3d vtNorm ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtTool, vtNorm)) { + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtTool, vtNorm)) + vtNorm = V_NULL ; + } + // determino fine uscita + Point3d ptP1 ; + if ( ! CalcLeadOutEnd( ptEnd, vtEnd, vtTool, vtNorm, ptP1)) + return false ; + // eventuale correzione fine uscita per evitare interferenze + if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptEnd, ptP1, vtTool, ptP1)) + return false ; + // aggiungo uscita + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, ptP1, vtTool, bSplitArcs)) { + m_pMchMgr->SetLastError( 3114, "Error in SurfFinishing : LeadOut not computable") ; + return false ; + } + // determino elevazione su fine uscita + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + dEndElev = dElev ; + dEndElev -= ( ptP1 - ptEnd) * vtTool ; + // se non è ultimo tratto, aggiungo retrazione di collegamento + if ( k < int( vpCrvs.size()) - 1) { + if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; + return false ; + } + } + // altrimenti aggiungo retrazione finale + else { + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 3115, "Error in SurfFinishing : Retract not computable") ; + return false ; } } } @@ -2138,128 +1772,10 @@ SurfFinishing::AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, return true ; } -//---------------------------------------------------------------------------- -bool -SurfFinishing::CalcOneWay( const ICurveComposite* pOffs, - ICRVCOMPOPOVECTOR& vpCrvs) -{ - // ingombro del contorno offsettato - BBox3d b3Pocket ; - pOffs->GetLocalBBox( b3Pocket) ; - Point3d ptMin ; double dDimX, dDimY, dDimZ ; - b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ; - - // lunghezza del contorno offsettato - double dLen ; pOffs->GetLength( dLen) ; - - // passi in Y - int nYStep = static_cast( ceil( ( dDimY - 20 * EPS_SMALL) / GetSideStep())) ; - double dYStep = ( nYStep > 0 ? ( dDimY - 20 * EPS_SMALL) / nYStep : 0) ; - - // tratto valido - struct Section { - bool bActive ; - Point3d ptS ; - Point3d ptE ; - double dOs ; - double dOe ; - } ; - // raccolta di tratti - typedef vector> VECVECSECT ; - - VECVECSECT vvSec ; - vvSec.resize( nYStep + 1) ; - - // calcolo le linee di svuotatura - int nCount = 0 ; - for ( int i = 0 ; i <= nYStep ; ++ i) { - // definisco la linea - PtrOwner pLine( CreateCurveLine()) ; - const double EXP_LEN = 1.0 ; - Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + 10 * EPS_SMALL + i * dYStep, ptMin.z + dDimZ) ; - if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) { - m_pMchMgr->SetLastError( 3110, "Error in SurfFinishing : Toolpath not computable") ; - return false ; - } - // calcolo la classificazione della curva rispetto al contorno esterno offsettato - IntersCurveCurve intCC( *pLine, *pOffs) ; - CRVCVECTOR ccClass ; - if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) { - m_pMchMgr->SetLastError( 3110, "Error in SurfFinishing : Toolpath not computable") ; - return false ; - } - // determino gli intervalli di curva da conservare - Intervals inOk ; - for ( auto& ccOne : ccClass) { - if ( ccOne.nClass == CRVC_IN || ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M) - inOk.Add( ccOne.dParS, ccOne.dParE) ; - } - // inserisco i tratti validi (sempre secondo X+) - double dParS, dParE ; - bool bFound = inOk.GetFirst( dParS, dParE) ; - while ( bFound) { - // determino i dati della sezione - Section Sect ; - Sect.bActive = true ; - pLine->GetPointD1D2( dParS, ICurve::FROM_PLUS, Sect.ptS) ; - pLine->GetPointD1D2( dParE, ICurve::FROM_MINUS, Sect.ptE) ; - pOffs->GetParamAtPoint( Sect.ptS, Sect.dOs, 10 * EPS_SMALL) ; - pOffs->GetParamAtPoint( Sect.ptE, Sect.dOe, 10 * EPS_SMALL) ; - // inserisco nel contenitore - vvSec[i].emplace_back( Sect) ; - ++ nCount ; - // recupero successivo intervallo - bFound = inOk.GetNext( dParS, dParE) ; - } - } - - // creo i percorsi di svuotatura - vpCrvs.reserve( nCount) ; - int nI = -1, nJ = -1 ; - while ( true) { - // se sezione non valida - if ( nI < 0 || nJ < 0) { - // ricerco la prima valida - for ( int k = 0 ; k < int( vvSec.size()) && nI < 0 ; ++ k) { - for ( int l = 0 ; l < int( vvSec[k].size()) && nJ < 0 ; ++ l) { - if ( vvSec[k][l].bActive) { - nI = k ; - nJ = l ; - } - } - } - // se trovata, creo nuova curva composita - if ( nI >= 0 && nJ >= 0) { - // creo la curva - vpCrvs.emplace_back( CreateCurveComposite()) ; - // aggiungo punto iniziale - vpCrvs.back()->AddPoint( vvSec[nI][nJ].ptS) ; - } - // altrimenti, esco - else - break ; - } - // aggiungo la sezione alla curva - Section& Sec = vvSec[nI][nJ] ; - Sec.bActive = false ; - vpCrvs.back()->AddLine( vvSec[nI][nJ].ptE) ; - nI = -1 ; - nJ = -1 ; - } - - // se richiesta percorrenza invertita - if ( m_Params.m_bInvert) { - for ( auto& pCompo : vpCrvs) - pCompo->Invert() ; - } - - return true ; -} - //---------------------------------------------------------------------------- bool SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, - const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut, bool bSkipMaxDown) + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) { // recupero distanze di sicurezza double dSafeZ = GetSafeZ() ; diff --git a/SurfFinishing.h b/SurfFinishing.h index 1a2bfba..8814c98 100644 --- a/SurfFinishing.h +++ b/SurfFinishing.h @@ -74,16 +74,12 @@ class SurfFinishing : public Machining bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; - bool AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs, bool bSkipMaxDown) ; - bool CalcZigZag( const ICurveComposite* pOffs, ICRVCOMPOPOVECTOR& vpCrvs) ; - bool AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs, bool bSkipMaxDown) ; - bool CalcOneWay( const ICurveComposite* pOffs, ICRVCOMPOPOVECTOR& vpCrvs) ; + bool AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; + bool AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; bool AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, - const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut, bool bSkipMaxDown) ; + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; bool AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; bool AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;