From 1395ba2c04bc4e8a101d20d2e4d50ca6bdf4828c Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Tue, 9 Jun 2026 15:18:37 +0200 Subject: [PATCH] EgtMachKernel : - in PocketingNT aggiunto Warning nel caso di svuotatura senza percorsi - in PocketingNT migliorata la gestione della superficie limite per isole aperte. --- PocketingNT.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++------- PocketingNT.h | 5 ++-- 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/PocketingNT.cpp b/PocketingNT.cpp index 5ebd016..955db18 100644 --- a/PocketingNT.cpp +++ b/PocketingNT.cpp @@ -116,6 +116,7 @@ static double FEED_MAX_COEFF = 1000. ; // 2457 = "Warning in PocketingNT : machining step (xxx) bigger than MaxMaterial (yyy)" // 2458 = "Warning in PocketingNT : machining depth (xxx) bigger than MaxMaterial (yyy)" // 2459 = "Warning in PocketingNT : No compensation in tool, so no compensation in machine" +// 2460 = "Warning in PocketingNT : Machining toolpath empty" //---------------------------------------------------------------------------- // Debug @@ -3027,12 +3028,52 @@ PocketingNT::CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRe if ( pSfrLimit == nullptr || ! pSfrLimit->IsValid()) return false ; // piccolo Offset di correzione - PtrOwner pSfrOffs( pSfrPock->CreateOffsetSurf( 10 * EPS_SMALL, ICurve::OFF_FILLET)) ; + PtrOwner pSfrOffs( pSfrPock->CreateOffsetSurf( 10. * EPS_SMALL, ICurve::OFF_FILLET)) ; if ( IsNull( pSfrOffs) || ! pSfrOffs->IsValid()) return false ; // sottrazione pSfrLimit->Subtract( *pSfrOffs) ; + // se la superficie corrente ha delle isole aperte interne al grezzo, la prevalenza va sulle isole aperte + // [NB. Queste isole potrebbero essere definite sul bordo del grezzo, seza che vengano riconosciute come lati aperti interni al grezzo, + // per estrerema sicurezza semplifico la regione Limite] + if ( pSfrLimit->IsValid()) { + for ( int nC = 0 ; nC < pSfrPock->GetChunkCount() && pSfrLimit->IsValid() ; ++ nC) { + int nLoopCnt = ( pSfrPock->GetLoopCount( nC)) ; + if ( nLoopCnt > 1) { + // raggio di riferimento per offset + double dOutEdge = 0.5 * m_TParams.m_dDiam ; + if ( m_Params.m_nSubType == POCKET_SPIRALIN || m_Params.m_nSubType == POCKET_ZIGZAG) + dOutEdge = max( dOutEdge, m_TParams.m_dDiam - m_Params.m_dSideStep) ; + double dExtension = dOutEdge + GetOffsR() + 100. * EPS_SMALL ; + for ( int nL = 1 ; nL < nLoopCnt && pSfrLimit->IsValid() ; ++ nL) { + PtrOwner pInternalLoop( ConvertCurveToComposite( pSfrPock->GetLoop( nC, nL))) ; + if ( IsNull( pInternalLoop) || ! pInternalLoop->IsValid()) + return false ; + ICRVCOMPOPOVECTOR vCrv ; + GetHomogeneousParts( pInternalLoop, vCrv) ; + if ( ssize( vCrv) == 1 && vCrv[0]->GetTempProp() == TEMP_PROP_OPEN_EDGE) { + // considero la curva come chiusa, le isole non sono definite + OffsetCurve OffsCrv ; + OffsCrv.Make( pInternalLoop, dExtension, ICurve::OFF_FILLET) ; + PtrOwner pCrvOffs( OffsCrv.GetLongerCurve()) ; + if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid()) { + SurfFlatRegionByContours SfrByC ; + SfrByC.AddCurve( Release( pCrvOffs)) ; + SfrByC.AddCurve( CloneCurveComposite( pInternalLoop)) ; + PtrOwner pSfrSub( SfrByC.GetSurf()) ; + if ( ! IsNull( pSfrSub) && pSfrSub->IsValid()) { + if ( AreOppositeVectorApprox( pSfrSub->GetNormVersor(), pSfrLimit->GetNormVersor())) + pSfrSub->Invert() ; + pSfrLimit->Subtract( *pSfrSub) ; + } + } + } + } + } + } + } + // se richiesto non controllo dei lati aperti if ( m_bOpenOutRaw && pSfrLimit->IsValid()) { double dExtension = 4. * m_TParams.m_dDiam + max( 0., m_dOpenMinSafe) + EPS_SMALL ; @@ -4049,6 +4090,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) } // se richiesta lavorazione + bool bEmptyPocket = false ; if ( nClId != GDB_ID_NULL) { // creo gruppo per geometria di lavorazione del percorso int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; @@ -4189,7 +4231,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) // calcolo le lavorazioni Point3d ptPockStart ; pSfr->GetCentroid( ptPockStart) ; Point3d ptPockEnd = ptPockStart ; - if ( ! AddPocket( vStepInfo, vtTool, dStep, bSplitArcs, ptPockStart, ptPockEnd)) + if ( ! AddPocket( vStepInfo, vtTool, dStep, bSplitArcs, ptPockStart, ptPockEnd, bEmptyPocket)) return false ; // assegno il vettore estrazione al gruppo del percorso @@ -4216,7 +4258,8 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) } // incremento numero di svuotature - ++ m_nPockets ; + if ( ! bEmptyPocket) + ++ m_nPockets ; return true ; } @@ -4701,11 +4744,12 @@ PocketingNT::CalcRetCurve( PathInfoPO& PathInfo, const StepInfoPO& StepInfo, con //---------------------------------------------------------------------------- bool -PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) +PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo, bool& bEmpty) { // se non ho Step, non faccio nulla if ( vStepInfo.empty()) return true ; + bEmpty = false ; // definisco il tipo di punto iniziale enum START_PT { DEFAULT = 0, BY_USER = 1, BY_HEAD = 2, BY_OPEN_GEO = 3, BY_CLOSE_GEO = 4} ; @@ -4800,8 +4844,11 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo) return false ; } // se non ho ottenuto percorsi, errore - if ( vCrvPaths.empty()) - return false ; + if ( vCrvPaths.empty()) { + m_pMchMgr->SetWarning( 2460, "Warning in PocketingNT : Machining toolpath empty") ; + bEmpty = true ; + return true ; + } // sistemo gli archi per massimo angolo al centro for ( int j = 0 ; j < ssize( vCrvPaths) ; ++ j) VerifyArcs( vCrvPaths[j]) ; @@ -5326,15 +5373,21 @@ PocketingNT::CalcDoubleParallelPenultimateStep( int nDouble, int nIdDblS, double //---------------------------------------------------------------------------- bool PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dStep, bool bSplitArcs, - Point3d& ptPockStart, Point3d& ptPockEnd) + Point3d& ptPockStart, Point3d& ptPockEnd, bool& bEmpty) { // se non ho superfici da svuotare, non faccio nulla if ( vStepInfo.empty()) return true ; // calcolo i percorsi di svuotatura per ogni Step/SubStep - if ( ! CalcPaths( vStepInfo)) + if ( ! CalcPaths( vStepInfo, bEmpty)) return false ; + // se svuotatura vuota, aggiorno la ProgressBar ed esco + if ( bEmpty) { + ExeProcessEvents( 100, 0) ; + return true ; + } + #if DEBUG_FEED nGrpDebugFeed = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; nLayDebugFeed = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpDebugFeed, GLOB_FRM) ; @@ -5669,7 +5722,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou } } - // aggiorno per sicurezza la ProgressBar nel caso di Step vuoti + // aggiorno per sicurezza la ProgressBar ExeProcessEvents( 100, 0) ; return true ; } diff --git a/PocketingNT.h b/PocketingNT.h index 78b19cb..8f4267c 100644 --- a/PocketingNT.h +++ b/PocketingNT.h @@ -137,10 +137,11 @@ class PocketingNT : public Machining bool CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& vtTool, double dDepth, const ISurfTriMesh* pStmRaw, const SELVECTOR& vGeoSel, ISURFFRPOVECTOR& vSfrGeoExt) ; bool CalcLimitRegion( const ISurfFlatRegion* pSfrPock, const ISurfFlatRegion* pSfrRaw, ISurfFlatRegion* pSfrLimit) ; - bool CalcPaths( STEPINFOPOVECTOR& vStepInfo) ; + bool CalcPaths( STEPINFOPOVECTOR& vStepInfo, bool& bEmpty) ; bool CalcRetCurve( PathInfoPO& PathInfo, const StepInfoPO& StepInfo, const ICurveComposite* pCrvPath, const Vector3d& vtTool, bool bHolePocketing, const Point3d& ptHoleDest, bool bToolComp, bool bInVsOut, ICurveComposite* pCrvGlide) ; - bool AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dStep, bool bSplitArcs, Point3d& ptPockStart, Point3d& ptPockEnd) ; + bool AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dStep, bool bSplitArcs, Point3d& ptPockStart, Point3d& ptPockEnd, + bool& bEmpty) ; double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ; double GetRightStartFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ; bool CutCurveWithLine( ICurveComposite* pCrvA, const ICurveLine* pCrvB) ;