From 67cce96f4ac7ea8a8704f56d20f223e91ec9d49b Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Wed, 24 Jun 2026 15:44:54 +0200 Subject: [PATCH] EgtMachKernel : - in PocketingNT esteso il controllo delle facce di una TriMesh - in PocketingNT forzato ricalcolo se modifica del flag Open. --- PocketingNT.cpp | 147 +++++++++++++++++++++++++++++++++--------------- PocketingNT.h | 1 + 2 files changed, 104 insertions(+), 44 deletions(-) diff --git a/PocketingNT.cpp b/PocketingNT.cpp index 79f8788..ff6f4d2 100644 --- a/PocketingNT.cpp +++ b/PocketingNT.cpp @@ -315,6 +315,7 @@ PocketingNT::PocketingNT( void) m_bAggrBottom = false ; m_bOpenOutRaw = false ; m_dOpenMinSafe = 0 ; + m_dOpen = -1. ; m_bRunning = false ; } @@ -706,6 +707,14 @@ PocketingNT::MyApply( bool bRecalc, bool bPostApply) // se modificata geometria, necessario ricalcolo if ( ( m_nStatus & MCH_ST_GEO_MODIF) != 0) bRecalc = true ; + // se modificato flag per lati aperti, forzo il ricalcolo + double dOpenOld = m_dOpen ; + double dOpen = -1 ; + GetValInNotes( m_Params.m_sUserNotes, UN_OPEN, dOpen) ; + if ( abs( dOpenOld - dOpen) > 10. * EPS_SMALL) { + m_dOpen = dOpen ; + bRecalc = true ; + } // verifico se necessario continuare nell'aggiornamento if ( ! bRecalc && ( m_nStatus == MCH_ST_OK || m_nStatus == MCH_ST_NO_POSTAPPL)) { @@ -3637,8 +3646,8 @@ PocketingNT::CheckMaxDepth( const ISurfFlatRegion* pSfr, double dDepth, const Ve //---------------------------------------------------------------------------- bool -PocketingNT::CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& vtTool, const double dDepth, const ISurfTriMesh* pStmRaw, - const SELVECTOR& vGeoSel, ISURFFRPOVECTOR& vSfrGeoExt) +PocketingNT::CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& vtTool, double dDepth, const ISurfTriMesh* pStmRaw, + const SELVECTOR& vGeoSel, ISURFFRPOVECTOR& vSfrGeoLimit) { // verifica valdità dei parametri if ( pSfrPock == nullptr || ! pSfrPock->IsValid() || pStmRaw == nullptr || ! pStmRaw->IsValid()) @@ -3687,14 +3696,13 @@ PocketingNT::CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& if ( IsNull( pSfrOrigFace) || ! pSfrOrigFace->IsValid()) return false ; #if DEBUG_SFR_GEO_EXT - int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrOrigFace->Clone()) ; - m_pGeomDB->SetMaterial( nId, Color( 0., 0., 1.)) ; - nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmRaw->Clone()) ; - m_pGeomDB->SetMaterial( nId, Color( 255, 165, 0, 50)) ; + int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStm->Clone()) ; + m_pGeomDB->SetMaterial( nId, Color( 0., .5, 0., 1.)) ; nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrOrigFace->Clone()) ; - m_pGeomDB->SetMaterial( nId, Color( 0., 1., 0., .5)) ; + m_pGeomDB->SetMaterial( nId, Color( 0., 1., 0., 1.)) ; #endif - // recupero tutte le facce adiacenti alla faccia selezionata + // -------------- analisi facce adiacenti, quindi perpendicolari alla faccia di svuotatura ---------------- + // recupero tutte le facce adiacenti e che formano lati chiusi con la faccia selezionata INTSET setAdjFace ; for ( int i = 0 ; i < ssize( vPL) ; ++ i) { double dPar ; @@ -3716,20 +3724,29 @@ PocketingNT::CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& bFound = vPL[i].GetNextU( dPar, true) ; } } - // scorro tutte le facce ad eccezione di quella da lavorare - for ( auto Iter = setAdjFace.begin() ; Iter != setAdjFace.end() ; ++ Iter) { + // da queste definisco una regione da non rovinare + for ( INTSET::iterator Iter = setAdjFace.begin() ; Iter != setAdjFace.end() ; ++ Iter) { int nAdjFace = *Iter ; // recupero il bordo della faccia - POLYLINEVECTOR vPL ; - pStm->GetFacetLoops( nAdjFace, vPL) ; - // definisco una geometria di estrusione in direzione opposta alla normale corrente - // NB. Considero solo il Loop esterno per le pareti verticali, non mi aspetto isole... - Vector3d vtFaceN ; pStm->GetFacetNormal( nAdjFace, vtFaceN) ; + POLYLINEVECTOR vPL ; pStm->GetFacetLoops( nAdjFace, vPL) ; + // definisco una geometria di estrusione in direzione opposta alla normale corrente (non considero isole) if ( ! vPL.empty()) { - PtrOwner pStm( CreateSurfTriMesh()) ; - if ( ! IsNull( pStm) && pStm->AdjustTopology() && pStm->CreateByExtrusion( vPL[0], 4. * m_TParams.m_dDiam * ( - vtFaceN))) { + // recupero la composita associata alla PolyLine + PtrOwner pCompoFaceLoop( CreateCurveComposite()) ; + pCompoFaceLoop->FromPolyLine( vPL[0]) ; + #if DEBUG_SFR_GEO_EXT + nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompoFaceLoop->Clone()) ; + m_pGeomDB->SetMaterial( nId, Color( 0., 0., 1., 1.)) ; + #endif + Vector3d vtFaceN ; pStm->GetFacetNormal( nAdjFace, vtFaceN) ; + PtrOwner pStmExtr( GetSurfTriMeshByExtrusion( pCompoFaceLoop, 4. * m_TParams.m_dDiam * ( - vtFaceN), true)) ; + if ( ! IsNull( pStmExtr)) { + #if DEBUG_SFR_GEO_EXT + nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmExtr->Clone()) ; + m_pGeomDB->SetMaterial( nId, Color( 0., 0., 1., 1.)) ; + #endif POLYLINEVECTOR vPLSil ; - if ( pStm->GetSilhouette( plFace, EPS_SMALL, vPLSil) && ! vPLSil.empty()) { + if ( pStmExtr->GetSilhouette( plFace, EPS_SMALL, vPLSil) && ! vPLSil.empty()) { PtrOwner pCompoLoop( CreateCurveComposite()) ; if ( ! IsNull( pCompoLoop) && pCompoLoop->FromPolyLine( vPLSil[0])) { PtrOwner pSfrCnt( CreateSurfFlatRegion()) ; @@ -3737,10 +3754,10 @@ PocketingNT::CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& if ( ! AreSameVectorApprox( pSfrCnt->GetNormVersor(), vtN)) pSfrCnt->Invert() ; // rimuovo tutto ciò che non è interno alla regione originale selezionata - pSfrCnt->Subtract( *pSfrOrigFace) ; - vSfrGeoExt.emplace_back( Release( pSfrCnt)) ; + //pSfrCnt->Subtract( *pSfrOrigFace) ; + vSfrGeoLimit.emplace_back( Release( pSfrCnt)) ; #if DEBUG_SFR_GEO_EXT - int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vSfrGeoExt.back()->Clone()) ; + nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vSfrGeoLimit.back()->Clone()) ; m_pGeomDB->SetMaterial( nId, Color( 1., 0., 0., .5)) ; #endif } @@ -3748,30 +3765,71 @@ PocketingNT::CalcGeoExtSurfFr( const ISurfFlatRegion* pSfrPock, const Vector3d& } } } - // se ho una regione valida - if ( ! vSfrGeoExt.empty()) { - for ( int i = 0 ; i < ssize( vSfrGeoExt) ; ++ i) { - // porto la superficie in globale - Frame3d frGlob ; m_pGeomDB->GetGlobFrame( Id.nId, frGlob) ; - vSfrGeoExt[i]->ToGlob( frGlob) ; - // la limito al grezzo - if ( ! IsNull( pSfrRaw) && pSfrRaw->IsValid()) { - vSfrGeoExt[i]->Intersect( *pSfrRaw) ; - if ( vSfrGeoExt[i]->IsValid()) { - // Assegno le proprietà di lato chiuso ad ogni parte trovata - for ( int nC = 0 ; nC < vSfrGeoExt[i]->GetChunkCount() ; ++ nC) { - for ( int nL = 0 ; nL < vSfrGeoExt[i]->GetLoopCount( nC) ; ++ nL) { - for ( int nU = 0 ; nU < vSfrGeoExt[i]->GetLoopCurveCount( nC, nL) ; ++ nU) - vSfrGeoExt[i]->SetCurveTempProp( nC, nL, nU, TEMP_PROP_CLOSE_EDGE, 0) ; - } - } - #if DEBUG_SFR_GEO_EXT - int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vSfrGeoExt[i]->Clone()) ; - m_pGeomDB->SetMaterial( nId, GRAY) ; - #endif - } - } + + // ------------- recupero eventuale Silhouette della TriMesh corrente al di sopra della faccia selezionata -------------- + const double TRIA_NUM = 500 ; + int nTriaCnt = pStm->GetTriangleCount() ; + bool bSimpleSil = ( nTriaCnt <= TRIA_NUM) ; + POLYLINEVECTOR vPLSil ; + if ( bSimpleSil) { + Plane3d plSil = plFace ; + plSil.Translate( 10. * EPS_SMALL * vtN) ; + bSimpleSil = ( pStm->GetSilhouette( plSil, EPS_SMALL, vPLSil)) ; + } + if ( ! bSimpleSil) { + vPLSil.clear() ; + Frame3d frFace ; + if ( ! frFace.Set( ptC + 10. * EPS_SMALL * vtN, vtN)) + return false ; + const double SIL_TOL = 1.0 ; + PtrOwner pCAvParDangSil( CreateCAvParSilhouettesSurfTm()) ; + if ( IsNull( pCAvParDangSil) || ! pCAvParDangSil->SetData( { pStm }, frFace, SIL_TOL)) + return false ; + if ( ! pCAvParDangSil->GetSilhouette( 0., vPLSil)) + return false ; + } + PtrOwner pSfrSil( nullptr) ; + if ( ! vPLSil.empty()) { + SurfFlatRegionByContours SfrByC ; + for ( const PolyLine& PL : vPLSil) { + PtrOwner pCompoLoop( CreateCurveComposite()) ; + if ( IsNull( pCompoLoop) || ! pCompoLoop->FromPolyLine( PL)) + return false ; + #if DEBUG_SFR_GEO_EXT + nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompoLoop->Clone()) ; + m_pGeomDB->SetMaterial( nId, ORANGE) ; + #endif + SfrByC.AddCurve( Release( pCompoLoop)) ; } + pSfrSil.Set( SfrByC.GetSurf()) ; + if ( ! IsNull( pSfrSil) && pSfrSil->IsValid()) { + if ( ! vSfrGeoLimit.emplace_back( ::Release( pSfrSil))) + return false ; + } + } + + // limito queste regioni alla presenza del grezzo + for ( int i = 0 ; i < ssize( vSfrGeoLimit) ; ++ i) { + // porto la superficie in globale + Frame3d frGlob ; m_pGeomDB->GetGlobFrame( Id.nId, frGlob) ; + vSfrGeoLimit[i]->ToGlob( frGlob) ; + // la limito al grezzo + if ( ! IsNull( pSfrRaw) && pSfrRaw->IsValid()) { + vSfrGeoLimit[i]->Intersect( *pSfrRaw) ; + if ( vSfrGeoLimit[i]->IsValid()) { + // Assegno le proprietà di lato chiuso ad ogni parte trovata + for ( int nC = 0 ; nC < vSfrGeoLimit[i]->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < vSfrGeoLimit[i]->GetLoopCount( nC) ; ++ nL) { + for ( int nU = 0 ; nU < vSfrGeoLimit[i]->GetLoopCurveCount( nC, nL) ; ++ nU) + vSfrGeoLimit[i]->SetCurveTempProp( nC, nL, nU, TEMP_PROP_CLOSE_EDGE, 0) ; + } + } + #if DEBUG_SFR_GEO_EXT + int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vSfrGeoLimit[i]->Clone()) ; + m_pGeomDB->SetMaterial( nId, GRAY) ; + #endif + } + } } } } @@ -3974,6 +4032,7 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId) CalcGeoExtSurfFr( pSfr, vtTool, 0., pStmRaw, vGeoSel, vSurfFrGeoExt) ; for ( int i = 0 ; i < ssize( vSurfFrGeoExt) ; ++ i) pSfr->Subtract( *vSurfFrGeoExt[i]) ; + if ( ! pSfr->IsValid()) return true ; // nulla da svuotare pSfr->Translate( vtTool * ( dDepth + m_TParams.m_dMaxMat)) ; diff --git a/PocketingNT.h b/PocketingNT.h index fa3c068..fd34296 100644 --- a/PocketingNT.h +++ b/PocketingNT.h @@ -253,5 +253,6 @@ class PocketingNT : public Machining double m_dOpenMinSafe ; // minima distanza di sicurezza di attacco su lato aperto double m_dOpenInRawExtension ; // estensione dei tratti aperti dentro al grezzo bool m_bAllClose ; // flag per forzare i lati come tutti chiusi + double m_dOpen ; // estensione lati aperti interno alla geometria del grezzo da note utente bool m_bRunning ; // flag di calcoli in corso } ; \ No newline at end of file