From 23388706929bed4c93d86f31056034a08bf7624b Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Thu, 11 Jun 2026 17:15:46 +0200 Subject: [PATCH] EgtMachKernel : - in Finitura aggiunta restrizione iniziale e finale dei percorsi in caso di parametro SkipMaxDown. --- SurfFinishing.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++-- SurfFinishing.h | 3 +- 2 files changed, 132 insertions(+), 5 deletions(-) diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 2327131..a037902 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -122,7 +122,9 @@ enum { #define ENABLE_OPTIMAL_FINAL_CURVES_DEBUG 0 #define ENABLE_PENCIL_DEBUG 0 #define ENABLE_LINK_DEBUG 0 -#if DEBUG || DEBUG_SFR || ENABLE_ZCONST_DEBUG || ENABLE_ZCONST_PATH_DEBUG || ENABLE_OPTIMAL_DEBUG || ENABLE_OPTIMAL_SOFT_DEBUG || ENABLE_PENCIL_DEBUG || ENABLE_OPTIMAL_FINAL_CURVES_DEBUG || ENABLE_LINK_DEBUG +#define ENABLE_MAXDOWN_STARTEND_DEBUG 0 +#if DEBUG || DEBUG_SFR || ENABLE_ZCONST_DEBUG || ENABLE_ZCONST_PATH_DEBUG || ENABLE_OPTIMAL_DEBUG || ENABLE_OPTIMAL_SOFT_DEBUG || \ + ENABLE_PENCIL_DEBUG || ENABLE_OPTIMAL_FINAL_CURVES_DEBUG || ENABLE_LINK_DEBUG || ENABLE_MAXDOWN_STARTEND_DEBUG #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkGeoVector3d.h" #include "/EgtDev/Include/EgtPerfCounter.h" @@ -1819,7 +1821,7 @@ SurfFinishing::SetCAvTlStmForSurfaces( ICAvToolSurfTm* pCAvTlStm, const ISurfFla //--------------------------------------------------------------------------- bool SurfFinishing::EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& frSurf, const Vector3d& vtMove, - double dDepth, ISurfFlatRegion* pSfrCnt) + double dDepth, ISurfFlatRegion* pSfrCnt) const { // controllo dei parametri if ( vSurfLoc.empty() || pSfrCnt == nullptr || ! pSfrCnt->IsValid()) @@ -1891,7 +1893,7 @@ SurfFinishing::EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& pSfrSil->ToGlob( frSurf) ; double dPockRadOffs = SILH_ARC_TOL ; pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ; - pSfrSil->Offset( m_TParams.m_dDiam / 2., ICurve::OFF_FILLET) ; + pSfrSil->Offset( m_TParams.m_dDiam, ICurve::OFF_FILLET) ; #if DEBUG_SFR int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; m_pGeomDB->SetName( nGrp, "FlatRegions MaxDown") ; @@ -1924,6 +1926,120 @@ SurfFinishing::EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& return true ; } +//---------------------------------------------------------------------------- +bool +SurfFinishing::EraseMaxDownStartEndPolyLine( PolyLine& PL) const +{ + // verifico che la PolyLine sia valida + if ( PL.GetPointNbr() <= 2) + return true ; + + const double START_END_LEN = 2. ; + + // Definisco la curva composita di non collisione iniziale + PtrOwner pCompoStartNoColl( CreateCurveComposite()) ; + if ( IsNull( pCompoStartNoColl)) + return false ; + + #if ENABLE_MAXDOWN_STARTEND_DEBUG + PNTULIST& _ptUList = PL.GetUPointList() ; + for ( const POINTU& _ptU : _ptUList) { + PtrOwner _pt( CreateGeoPoint3d()) ; _pt->Set( _ptU.first) ; + int _nPtId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ::Release( _pt)) ; + m_pGeomDB->SetMaterial( _nPtId, RED) ; + } + #endif + + // scorro i punti della PolyLine + PNTULIST& ptUList = PL.GetUPointList() ; + bool bFirst = true ; + for ( PNTULIST::iterator Iter = ptUList.begin() ; Iter != ptUList.end() ; ++ Iter) { + if ( bFirst) { + pCompoStartNoColl->AddPoint( ( *Iter).first) ; + bFirst = false ; + } + else + pCompoStartNoColl->AddLine( ( *Iter).first) ; + // al primo punto di collisione trovato + if ( ( *Iter).second > EPS_SMALL) { + // verifico se curva sufficientemente lunga + double dLen = 0. ; pCompoStartNoColl->GetLength( dLen) ; + if ( dLen > START_END_LEN) { + pCompoStartNoColl->TrimStartAtLen( dLen - START_END_LEN) ; + ptUList.erase( ptUList.begin(), Iter) ; + pCompoStartNoColl->Invert() ; + for ( int nU = 0 ; nU < pCompoStartNoColl->GetCurveCount() ; ++ nU) { + const ICurve* pCrv = pCompoStartNoColl->GetCurve( nU) ; + if ( pCrv != nullptr && pCrv->IsValid()) { + Point3d ptS ; pCrv->GetStartPoint( ptS) ; + ptUList.emplace_front( make_pair( ptS, 0.)) ; + } + } + Point3d ptListStart ; pCompoStartNoColl->GetEndPoint( ptListStart) ; + if ( ! AreSamePointApprox( ptUList.front().first, ptListStart)) + ptUList.emplace_front( make_pair( ptListStart, 0.)) ; + } + #if ENABLE_MAXDOWN_STARTEND_DEBUG + PtrOwner _pt( CreateGeoPoint3d()) ; _pt->Set( ( *Iter).first) ; + int _nPtId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ::Release( _pt)) ; + m_pGeomDB->SetMaterial( _nPtId, LIME) ; + int _nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ::CloneCurveComposite( pCompoStartNoColl)) ; + m_pGeomDB->SetMaterial( _nCrvId, AQUA) ; + #endif + + break ; + } + } + + // dalla fine della PolyLine, ripeto le considerazioni fatte + // scorro i punti della PolyLine + bFirst = true ; + pCompoStartNoColl->Clear() ; + for ( PNTULIST::reverse_iterator Iter = ptUList.rbegin() ; Iter != ptUList.rend() ; ++ Iter) { + if ( bFirst) { + pCompoStartNoColl->AddPoint( ( *Iter).first) ; + bFirst = false ; + } + else + pCompoStartNoColl->AddLine( ( *Iter).first) ; + // al primo punto di collisione trovato + if ( ( *Iter).second > EPS_SMALL) { + #if ENABLE_MAXDOWN_STARTEND_DEBUG + PtrOwner _pt( CreateGeoPoint3d()) ; _pt->Set( ( *Iter).first) ; + int _nPtId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ::Release( _pt)) ; + m_pGeomDB->SetMaterial( _nPtId, LIME) ; + #endif + // verifico se curva sufficientemente lunga + double dLen = 0. ; pCompoStartNoColl->GetLength( dLen) ; + if ( dLen > START_END_LEN) { + pCompoStartNoColl->TrimStartAtLen( dLen - START_END_LEN) ; + // recupero l'iteratore corretto + PNTULIST::iterator myIter = Iter.base() ; -- Iter ; + ptUList.erase( myIter, ptUList.end()) ; + pCompoStartNoColl->Invert() ; + for ( int nU = 0 ; nU < pCompoStartNoColl->GetCurveCount() ; ++ nU) { + const ICurve* pCrv = pCompoStartNoColl->GetCurve( nU) ; + if ( pCrv != nullptr && pCrv->IsValid()) { + Point3d ptS ; pCrv->GetStartPoint( ptS) ; + ptUList.emplace_back( make_pair( ptS, 0.)) ; + } + } + Point3d ptListStart ; pCompoStartNoColl->GetEndPoint( ptListStart) ; + if ( ! AreSamePointApprox( ptUList.front().first, ptListStart)) + ptUList.emplace_back( make_pair( ptListStart, 0.)) ; + } + #if ENABLE_MAXDOWN_STARTEND_DEBUG + int _nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ::CloneCurveComposite( pCompoStartNoColl)) ; + m_pGeomDB->SetMaterial( _nCrvId, AQUA) ; + #endif + + break ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool SurfFinishing::ProcessCrv( int nPathId, int nPvId, int nClId) @@ -2476,6 +2592,10 @@ SurfFinishing::CorrectPathByCollision( ICAvToolSurfTm* pCAvTlStm, const Frame3d& const double MAX_DIST = 50. ; double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; + // se presente Flag di SkipMaxDown, elimino le parti iniziali e finali dei percorsi che non hanno subito una collisione + bool bEraseStartEndMaxDown = false ; + GetValInNotes( m_Params.m_sUserNotes, UN_SKIPMAXDOWN, bEraseStartEndMaxDown) ; + // scorro le curve double dProgCoeff = 1. / max( int( vpCrvs.size()), 1) ; for ( int i = 0 ; i < ssize( vpCrvs) ; ++ i) { @@ -2501,6 +2621,9 @@ SurfFinishing::CorrectPathByCollision( ICAvToolSurfTm* pCAvTlStm, const Frame3d& PL.Translate( - vtToolL * m_TParams.m_dLen) ; // riporto la polilinea nel riferimento della curva PL.ToGlob( frSurf) ; + // se devo eliminare i punti inziali e finali senza collisione, modifico la PolyLine + if ( bEraseStartEndMaxDown) + EraseMaxDownStartEndPolyLine( PL) ; // elimino i punti allineati PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; // creo una curva composita a partire dalla polilinea @@ -6260,6 +6383,9 @@ SurfFinishing::CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const if ( ! pSfrZigZag->Subtract( *pSfrZLevelColl)) return false ; if ( pSfrZigZag->IsValid()) { + // Offset di confine tra passata Zlevel e ZigZag (per sicurezza è meglio lasciare questo valore non nullo, dato che la CAv è fatta + // su una PolyLine che potrebbe approssimare archi, trovando quindi collisioni nei punti intermedi di esso creando Spike verticali) + const double EXTRA_OFFS_TOL = 200. * EPS_SMALL ; // (alzare se necessario) for ( int nC = 0 ; nC < pSfrZigZag->GetChunkCount() ; ++ nC) { PtrOwner pSfrZigZagChunk( pSfrZigZag->CloneChunk( nC)) ; if ( ! IsNull( pSfrZigZagChunk) && pSfrZigZagChunk->IsValid()) { @@ -6272,7 +6398,7 @@ SurfFinishing::CalcOptimalZigZagRegion( const ISurfFlatRegion* pSfrCntLoc, const pSfrZigZagChunk->Offset( m_TParams.m_dDiam / 2., ICurve::OFF_FILLET) ; // tutti i lati della superficie vengono considerati come chiusi, quindi per portare l'utensile lungo // i bordi estendo la superficie del raggio utensile - if ( ! pSfrZigZagChunk->Offset( m_TParams.m_dDiam / 2. - 5. * EPS_SMALL, ICurve::OFF_FILLET)) + if ( ! pSfrZigZagChunk->Offset( m_TParams.m_dDiam / 2. - EXTRA_OFFS_TOL, ICurve::OFF_FILLET)) return false ; for ( int nC = 0 ; nC < pSfrZigZagChunk->GetChunkCount() ; ++ nC) { for ( int nL = 0 ; nL < pSfrZigZagChunk->GetLoopCount( nC) ; ++ nL) { diff --git a/SurfFinishing.h b/SurfFinishing.h index 40c019b..00e5585 100644 --- a/SurfFinishing.h +++ b/SurfFinishing.h @@ -118,7 +118,8 @@ class SurfFinishing : public Machining double dToolSideAng, double dToolMaxMat, double dMachOffsR, const SURFLOCALVECTOR& vSurfLoc, const SURFLOCALVECTOR& vSurfSuppLoc) ; bool EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& frSurf, const Vector3d& vtMove, - double dDepth, ISurfFlatRegion* pSfrCnt) ; + double dDepth, ISurfFlatRegion* pSfrCnt) const ; + bool EraseMaxDownStartEndPolyLine( PolyLine& PL) const ; bool ProcessCrv( int nPathId, int nPvId, int nClId) ; bool ProcessSfr( int nPathId, int nPvId, int nClId) ; bool SimplifyCurve( ICurveComposite* pCompo, const Frame3d& frLocXY,