From 8c4c606ee1ce59ddd01e7e36a1b4ba39b65d8a69 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 3 Jun 2024 08:16:08 +0200 Subject: [PATCH] EgtMachKernel 2.6f1 : - modifiche per sgrossatura superfici. --- EgtMachKernel.rc | Bin 11774 -> 11774 bytes SurfFinishing.cpp | 3 +- SurfRoughing.cpp | 733 +++++++--------------------------------------- SurfRoughing.h | 11 +- 4 files changed, 113 insertions(+), 634 deletions(-) diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index 8c23b910822a0f073e0f2be7ffc5f01c47368e34..41c046c7cdf3156f15e0dae37c98468caf5daf78 100644 GIT binary patch delta 121 zcmewt{V#gMH#Sx?1|0^&&A-{KnVHiV3@1O7)ZLuM)x!c8zsNNCgkT;*P6$a3MUMyL R=2g-z%(yjz6ex#q0RV5MCZGTS delta 121 zcmewt{V#gMH#SyN1|0^o&A-{KnVC}=%qBmS)ZLuM)x!c8zsNNCgkT;*P6$a3MUMyL R=2g-z%(yjz6ex#q0RVTECcppy diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index c89e335..7e35ea6 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -26,8 +26,7 @@ #include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EGkChainCurves.h" #include "/EgtDev/Include/EGkOffsetCurve.h" -#include "/EgtDev/Include/EGkOffsetCurveOnX.h" -#include "/EgtDev/Include/EGkSfrCreate.h" +#include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkSurfLocal.h" #include "/EgtDev/Include/EGkCAvToolSurfTm.h" #include "/EgtDev/Include/EGkIntervals.h" diff --git a/SurfRoughing.cpp b/SurfRoughing.cpp index 87855ee..b8dc4ee 100644 --- a/SurfRoughing.cpp +++ b/SurfRoughing.cpp @@ -26,10 +26,9 @@ #include "/EgtDev/Include/EGkArcSpecial.h" #include "/EgtDev/Include/EGkChainCurves.h" #include "/EgtDev/Include/EGkOffsetCurve.h" -#include "/EgtDev/Include/EGkOffsetCurveOnX.h" +#include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkSfrCreate.h" -#include "/EgtDev/Include/EGkSurfLocal.h" -#include "/EgtDev/Include/EGkCAvToolSurfTm.h" +#include "/EgtDev/Include/EGkCalcPocketing.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUserObjFactory.h" @@ -63,6 +62,8 @@ using namespace std ; // 3020 = "Error in SurfRoughing : post apply not calculable" // 3021 = "Error in SurfRoughing : Linear Approx not computable" // 3022 = "Error in SurfRoughing : aggregate from bottom not allowed" +// 3023 = "Error in SurfRoughing : missing surfaces" +// 3024 = "Error in SurfRoughing : region not computable" // 3051 = "Warning in SurfRoughing : Skipped entity (xx)" // 3052 = "Warning in SurfRoughing : No machinable path" // 3053 = "Warning in SurfRoughing : Tool name changed (xx)" @@ -574,11 +575,28 @@ SurfRoughing::Apply( bool bRecalc, bool bPostApply) else m_pGeomDB->EmptyGroup( nClId) ; + // recupero gruppo per geometria temporanea + const string GRP_TEMP = "Temp" ; + int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ; + // se non c'è, lo aggiungo + if ( nTempId == GDB_ID_NULL) { + nTempId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; + if ( nTempId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nTempId, GRP_TEMP) ; + } + // altrimenti lo svuoto + else + 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) ; + // lavoro ogni singola catena bool bOk = true ; int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; while ( nPathId != GDB_ID_NULL) { - if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId)) + if ( ! ProcessPath( nPathId, nTempId, GDB_ID_NULL, nClId)) bOk = false ; nPathId = m_pGeomDB->GetNextGroup( nPathId) ; } @@ -1090,25 +1108,8 @@ SurfRoughing::Chain( int nGrpDestId) //---------------------------------------------------------------------------- bool -SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) +SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) { - // recupero gruppo per geometria temporanea - const string GRP_TEMP = "Temp" ; - int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ; - // se non c'è, lo aggiungo - if ( nTempId == GDB_ID_NULL) { - nTempId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; - if ( nTempId == GDB_ID_NULL) - return false ; - m_pGeomDB->SetName( nTempId, GRP_TEMP) ; - } - // altrimenti lo svuoto - else - 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) ; - // verifico sia una curva chiusa (deve delimitare l'area da svuotare) int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; if ( m_pGeomDB->GetGeoType( nCrvId) != CRV_COMPO) @@ -1143,6 +1144,8 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) } if ( plPlane.GetVersN() * vtExtr * dArea < 0) pCompo->Invert() ; + if ( plPlane.GetVersN() * vtExtr < 0) + plPlane.Invert() ; // unisco le parti allineate if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true)) @@ -1164,6 +1167,9 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) return false ; } + // verifico ed eventualmente aggiusto lo step + double dOkStep = min( m_Params.m_dStep, m_TParams.m_dMaxMat + EPS_SMALL) ; + // recupero nome del path string sPathName ; m_pGeomDB->GetName( nPathId, sPathName) ; @@ -1171,6 +1177,8 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) // assegno il versore fresa Vector3d vtTool = vtExtr ; + // non prevista gestione anteprima di lavorazione + // se richiesta lavorazione if ( nClId != GDB_ID_NULL) { // creo gruppo per geometria di lavorazione del percorso @@ -1183,55 +1191,61 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) // verifico se archi vanno approssimati con segmenti di retta bool bSplitArcs = GetSplitArcs( vtTool) ; - // predispongo l'ambiente di correzione dei percorsi utensili con le superfici attive dei pezzi - PtrOwner pCAvTlStm( CreateCAvToolSurfTm()) ; - if ( IsNull( pCAvTlStm)) - return false ; - if ( abs( m_TParams.m_dSideAng) < EPS_ANG_SMALL) { - pCAvTlStm->SetStdTool( m_TParams.m_dLen + GetOffsR(), - m_TParams.m_dDiam / 2 + GetOffsR(), - m_TParams.m_dCornRad + GetOffsR()) ; - } - else { - double dDelta ; - double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ; - if ( m_TParams.m_dSideAng > 0) { - if ( m_TParams.m_dCornRad < EPS_SMALL) - dDelta = 2 * m_TParams.m_dMaxMat * tan( dSideAngRad) ; - else - dDelta = 2 * ( m_TParams.m_dCornRad * cos( dSideAngRad) + - ( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad)) ; - } - else { - dDelta = 2 * tan( dSideAngRad) * m_TParams.m_dMaxMat ; - } - double dStemRad = m_TParams.m_dDiam / 2 + dDelta ; - double dTipRad = m_TParams.m_dDiam / 2 ; - pCAvTlStm->SetAdvTool( m_TParams.m_dLen + GetOffsR(), - dStemRad + GetOffsR(), - m_TParams.m_dMaxMat, - dTipRad + GetOffsR(), - m_TParams.m_dCornRad + GetOffsR()) ; - } - Frame3d frSurf ; - const ISurfTriMesh* pStm = nullptr ; - SURFLOCALVECTOR vSrfLoc ; + // recupero le superfici attive INTVECTOR vSurfId ; GetActiveSurfaces( vSurfId) ; - for ( auto nSurfId : vSurfId) { - if ( pStm == nullptr) { - pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nSurfId)) ; - if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf)) - return false ; - pCAvTlStm->SetSurfTm( *pStm) ; + if ( vSurfId.empty()) { + m_pMchMgr->SetLastError( 3023, "Error in SurfRoughing : missing surfaces") ; + return false ; + } + + // calcolo le regioni di svuotatura alle varie quote come differenza tra regioni da lavorare e regioni di silhouette + INTVECTOR vPocket ; + const double SILH_TOL = max( GetOffsR(), 1.) ; + int nStep = max( 1, static_cast( ceil( dDepth / dOkStep))) ; + double dStep = dDepth / nStep ; + for ( int i = 1 ; i <= nStep ; ++ i) { + // regione di lavoro allo step corrente + PtrOwner pSfr( CreateSurfFlatRegion()) ; + if ( IsNull( pSfr) || ! pSfr->AddExtLoop( *pCompo)) { + m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ; + return false ; } - else { - vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ; - pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc.back().Get())) ; + pSfr->Translate( -i * dStep * vtTool) ; + // piano di taglio per silhouette (compreso di offset longitudinale) + Plane3d plCut = plPlane ; + plCut.Translate( - ( i * dStep + GetOffsL()) * vtTool) ; + // per ogni superficie + for ( int nSurfId : vSurfId) { + const ISurfTriMesh* pSurf = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nSurfId)) ; + Frame3d frSurf ; m_pGeomDB->GetGlobFrame( nSurfId, frSurf) ; + Plane3d plCutL = plCut ; plCutL.ToLoc( frSurf) ; + // determino le regioni da non lavorare e le sottraggo + POLYLINEVECTOR vPL ; + if ( pSurf == nullptr || ! pSurf->GetSilhouette( plCutL, SILH_TOL, vPL)) { + m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ; + return false ; + } + for ( auto& PL : vPL) { + PtrOwner pSfrSil( GetSurfFlatRegionFromPolyLine( PL)) ; + if ( IsNull( pSfrSil)) { + m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ; + return false ; + } + pSfrSil->ToGlob( frSurf) ; + pSfr->Subtract( *pSfrSil) ; + } + } + // se regione risultante non vuota, la salvo nel gruppo temporaneo + if ( pSfr->IsValid()) { + int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfr)) ; + if ( nNewId == GDB_ID_NULL) { + m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ; + return false ; + } + vPocket.emplace_back( nNewId) ; } } - if ( pStm == nullptr) - pCAvTlStm.Reset() ; // assegno il vettore estrazione al gruppo del percorso m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; @@ -1240,23 +1254,10 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) SetPathId( nPxId) ; SetToolDir( vtTool) ; - // Eseguo la lavorazione a seconda del tipo + // Eseguo le svuotature double dElev = dDepth ; - switch ( m_Params.m_nSubType) { - case SURFFIN_SUB_ONEWAY : - case SURFFIN_SUB_ZIGZAG : - if ( ! AddZigZag( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) - return false ; - break ; - case SURFFIN_SUB_SPIRALIN : - if ( ! AddSpiral( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs, true)) - return false ; - break ; - case SURFFIN_SUB_SPIRALOUT : - if ( ! AddSpiral( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs, false)) - return false ; - break ; - } + if ( ! AddPocket( vPocket, vtTool, vtExtr, dDepth, dElev, bSplitArcs)) + return false ; } // incremento numero di percorsi @@ -1316,80 +1317,25 @@ SurfRoughing::GetActiveSurfaces( INTVECTOR& vSurfId) const //---------------------------------------------------------------------------- bool -SurfRoughing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs) +SurfRoughing::AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const Vector3d& vtExtr, + double dDepth, double dElev, bool bSplitArcs) { // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - // calcolo curva offsettata del raggio utensile - double dOffs = - 0.5 * m_TParams.m_dDiam ; - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCompo, dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 3009, "Error in SurfRoughing : Offset not computable") ; - return false ; - } - - // ciclo sulle curve risultanti + // ciclo sulle regioni bool bStart = true ; - while ( OffsCrv.GetCurveCount() > 0) { - // recupero la prima curva di offset - PtrOwner pOffs ; - if ( ! pOffs.Set( ConvertCurveToComposite( OffsCrv.GetLongerCurve()))) { - m_pMchMgr->SetLastError( 3010, "Error in SurfRoughing : Toolpath not computable") ; - return false ; - } - // 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 + for ( int nPockId : vPocket) { + // calcolo la svuotatura + const ISurfFlatRegion* pSfr = GetSurfFlatRegion( m_pGeomDB->GetGeoObj( nPockId)) ; ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcZigZag( pOffs, vpCrvs)) + if ( ! CalcPocketing( pSfr, m_TParams.m_dDiam / 2, m_Params.m_dSideStep, m_Params.m_dSideAngle, + m_Params.m_nSubType, true, 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) ; - // 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) { @@ -1399,7 +1345,6 @@ SurfRoughing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, PtrOwner pCurve( pCrvC->Clone()) ; if ( IsNull( pCurve)) return false ; - pCurve->ToGlob( frPocket) ; // se prima entità if ( i == 0 ) { // dati inizio entità @@ -1439,14 +1384,25 @@ SurfRoughing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, } } // 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 ; + if ( pCurve->GetType() == CRV_LINE) { + ICurveLine* pLine = GetCurveLine( pCurve) ; + Point3d ptP3 = pLine->GetEnd() ; + Vector3d vtMove ; pLine->GetStartDir( vtMove) ; + SetFeed( GetRightFeed( vtMove, vtTool)) ; + 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) { // dati fine entità @@ -1487,475 +1443,6 @@ SurfRoughing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, return true ; } -//---------------------------------------------------------------------------- -bool -SurfRoughing::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( 3010, "Error in SurfRoughing : 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( 3010, "Error in SurfRoughing : 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 ; - } - } - else { - if ( dU > dUstart) - dU -= dUspan ; - if ( dU > dUref) { - dUref = dU ; - nNextI = k ; - nNextJ = l ; - } - } - } - 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 ; -} - -//---------------------------------------------------------------------------- -bool -SurfRoughing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) -{ - // recupero distanze di sicurezza - double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; - // lunghezza di approccio/retrazione - double dAppr = m_Params.m_dStartPos ; - - // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine - PtrOwner pMCrv( CreateCurveComposite()) ; - if ( IsNull( pMCrv)) { - m_pMchMgr->SetLastError( 3009, "Error in SurfRoughing : Offset not computable") ; - return false ; - } - if ( ! CalcSpiral( pCompo, false, pMCrv, nullptr)) - return false ; - if ( ! bInVsOut) - pMCrv->Invert() ; - - // ciclo sulle curve risultanti - bool bStart = true ; - if ( true) { - // 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) ; - pMCrv->ToLoc( frPocket) ; - // ciclo sui percorsi - if ( true) { - // li correggo per non interferire con le superfici - if ( pCAvTlStm != nullptr) { - // approssimo la curva con una polilinea - PolyLine PL ; - if ( ! pMCrv->ApproxWithLines( m_Params.m_dApprox, 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) ; - // 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) ; - } - // 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) ; - // determino inizio attacco - Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, 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( 3011, "Error in SurfRoughing : Approach not computable") ; - return false ; - } - bStart = false ; - } - // altrimenti, approccio di collegamento - else { - if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { - m_pMchMgr->SetLastError( 3012, "Error in SurfRoughing : Link not computable") ; - return false ; - } - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bSplitArcs)) { - m_pMchMgr->SetLastError( 3013, "Error in SurfRoughing : 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) ; - // determino elevazione su uscita - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) - dEndElev = dElev ; - // aggiungo uscita - Point3d ptP1 ; - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, ptP1, bSplitArcs)) { - m_pMchMgr->SetLastError( 3014, "Error in SurfRoughing : LeadOut not computable") ; - return false ; - } - // se non è ultimo tratto, aggiungo retrazione di collegamento - if ( false) { - if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 3012, "Error in SurfRoughing : Link not computable") ; - return false ; - } - } - // altrimenti aggiungo retrazione finale - else { - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 3015, "Error in SurfRoughing : Retract not computable") ; - return false ; - } - } - } - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -static double -GetCurveRadius( const ICurve* pCrv) -{ - if ( pCrv == nullptr) - return 0.0 ; - BBox3d b3Loc ; - if ( ! pCrv->GetLocalBBox( b3Loc, BBF_EXACT)) - return 0.0 ; - double dRad ; - if ( ! b3Loc.GetRadius( dRad)) - return 0.0 ; - return dRad ; -} - -//---------------------------------------------------------------------------- -bool -SurfRoughing::CalcSpiral( const ICurveComposite* pCompo, bool bSplitArcs, - ICurveComposite* pMCrv, ICurveComposite* pRCrv) -{ - // primo offset pari al raggio utensile - overlap - double dTRad = 0.5 * m_TParams.m_dDiam ; - double dOffs = dTRad ; - - // ciclo di offset verso l'interno - const int MAX_ITER = 1000 ; - int nIter = 0 ; - PtrOwner pOffs ; - const ICurve* pCurr = pCompo ; - double dCurrRad = GetCurveRadius( pCurr) ; - while ( nIter < MAX_ITER) { - // calcolo - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCurr, - dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 3009, "Error in SurfRoughing : Offset not computable") ; - return false ; - } - // recupero la prima curva di offset - PtrOwner pNextOffs( OffsCrv.GetLongerCurve()) ; - double dRad = GetCurveRadius( pNextOffs) ; - bool bNextOk = ( dRad > EPS_ZERO && dRad < dCurrRad) ; - bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + EPS_ZERO : dOffs < dTRad + EPS_ZERO) ; - // se completato step di offset, accodo la curva offsettata al percorso di lavoro - if ( ! IsNull( pOffs) && ( bNextOk || bSmallRad)) { - // verifico se aggiungere linea di congiunzione - if ( pMCrv->GetCurveCount() > 0) { - Point3d ptStart ; - pOffs->GetStartPoint( ptStart) ; - // aggiungo al percorso principale - pMCrv->AddLine( ptStart) ; - // eventuale copia nel percorso di ritorno - if ( pRCrv != nullptr) - pRCrv->AddCurve( *pMCrv->GetLastCurve()) ; - } - // se richiesta percorrenza invertita - if ( m_Params.m_bInvert) - pOffs->Invert() ; - // aggiungo la curva - pMCrv->AddCurve( Release( pOffs)) ; - } - // se offset va bene - if ( bNextOk) { - // sistemo per prossimo step - dCurrRad = dRad ; - pOffs.Set( pNextOffs) ; - pCurr = Get( pOffs) ; - // nuovo valore pari allo step - dOffs = GetSideStep() ; - } - // se altrimenti riducibile, provo con offset ridotto al raggio utensile - else if ( ! bSmallRad) { - // nuovo valore pari al raggio - dOffs = dTRad ; - } - // altrimenti esco - else - break ; - // incremento contatore iterazioni - ++ nIter ; - } - - // verifico il percorso di lavoro - if ( pMCrv->GetCurveCount() == 0) { - m_pMchMgr->SetLastError( 3010, "Error in SurfRoughing : : Toolpath not computable") ; - return false ; - } - // se necessario, approssimo archi con rette - if ( bSplitArcs && ! ApproxWithLines( pMCrv)) { - m_pMchMgr->SetLastError( 3021, "Error in SurfRoughing : Linear Approx not computable") ; - return false ; - } - // eventuale sistemazione archi - VerifyArcs( pMCrv) ; - // eventualmente compatto e inverto il percorso di ritorno - if ( pRCrv != nullptr) { - pRCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false) ; - pRCrv->Invert() ; - } - - return true ; -} - //---------------------------------------------------------------------------- bool SurfRoughing::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) diff --git a/SurfRoughing.h b/SurfRoughing.h index 43b4db3..6a8e042 100644 --- a/SurfRoughing.h +++ b/SurfRoughing.h @@ -72,16 +72,9 @@ class SurfRoughing : public Machining bool VerifyGeometry( SelData Id, int& nSubs) ; 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, + bool ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) ; + bool AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, bool bSplitArcs) ; - bool CalcZigZag( const ICurveComposite* pOffs, ICRVCOMPOPOVECTOR& vpCrvs) ; - bool AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) ; - bool CalcSpiral( const ICurveComposite* pCompo, bool bSplitArcs, - ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; 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) ;