From ba9bf97372cbcd71bb51e53c200bc48f33241954 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Tue, 17 Jun 2025 14:31:12 +0200 Subject: [PATCH] EgtMachKernel : - In finiture primo utilizzo delle funzioni di Offset per superfici di supporto - in finiture semplicificazione e riorganizzazione del codice. --- SurfFinishing.cpp | 478 ++++++++++++++++++++++++++++------------------ SurfFinishing.h | 9 +- 2 files changed, 294 insertions(+), 193 deletions(-) diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 07e505d..31acf8d 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -41,6 +41,7 @@ #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkDistPointSurfFr.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" +#include "/EgtDev/Include/EGkStmFromCurves.h" #include #include // per far dimenticare macro di WinUser.h @@ -86,12 +87,15 @@ using namespace std ; //---------------------------------------------------------------------------- static string KEY_THICK = "THICK" ; +static string SRF_SUPP_LAYER_NAME = "SUPP" ; const double SILH_SAMPLING = 1. ; +const double SUPP_SURF_RADIAL_OFFS = 5. ; +#define DEBUG_SFR 0 #define ENABLE_ZCONST_DEBUG 0 #define ENABLE_OPTIMAL_DEBUG 0 #define ENABLE_OPTIMAL_SOFT_DEBUG 0 -#if ENABLE_ZCONST_DEBUG || ENABLE_OPTIMAL_DEBUG || ENABLE_OPTIMAL_SOFT_DEBUG +#if DEBUG_SFR || ENABLE_ZCONST_DEBUG || ENABLE_OPTIMAL_DEBUG || ENABLE_OPTIMAL_SOFT_DEBUG #include "EgtDev/Include/EGkGeoPoint3d.h" #include "EgtDev/Include/EGkGeoVector3d.h" #include "chrono" @@ -1267,6 +1271,209 @@ SurfFinishing::Chain( int nGrpDestId) return true ; } +//---------------------------------------------------------------------------- +bool +SurfFinishing::GetSurfacesByIds( SURFLOCALVECTOR& vSrfLoc, SURFLOCALVECTOR& vSrfSuppLoc, Frame3d& frSurf) +{ + /* funzione che restituisce le superfici attive, le superfici di supporto e il frame di riferimento */ + vSrfLoc.clear() ; + vSrfSuppLoc.clear() ; + // recupero le superfici attive e le superfici nel Layer di supporto + INTVECTOR vSurfId, vSurfSuppId ; + GetActiveSurfaces( vSurfId, vSurfSuppId) ; + // porto tutte le superfici nel riferimento della prima + for ( int& nSurfId : vSurfId) { + if ( vSrfLoc.empty()) { + if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf)) + return false ; + } + vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ; + } + if ( ! frSurf.IsValid()) + return false ; + for ( int& nSrfSuppId : vSurfSuppId) + vSrfSuppLoc.emplace_back( m_pGeomDB, nSrfSuppId, frSurf) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfFinishing::SetCAvTlStmForSurfaces( ICAvToolSurfTm* pCAvTlStm, const ISurfFlatRegion* pSfrCnt, double dDepth, + SURFLOCALVECTOR& vSurfLoc, SURFLOCALVECTOR& vSurfSuppLoc) +{ + // controllo dei parametri + if ( pCAvTlStm == nullptr || vSurfLoc.empty()) + return false ; + + // definisco l'ambiente di correzione dei percorsi utensili + 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 dDeltaRad ; + double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ; + if ( m_TParams.m_dSideAng > 0) { + if ( m_TParams.m_dCornRad < EPS_SMALL) + dDeltaRad = m_TParams.m_dMaxMat * tan( dSideAngRad) ; + else + dDeltaRad = m_TParams.m_dCornRad * cos( dSideAngRad) + + ( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad) ; + } + else + dDeltaRad = tan( dSideAngRad) * m_TParams.m_dMaxMat ; + double dStemRad = m_TParams.m_dDiam / 2. + dDeltaRad ; + 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()) ; + } + + // aggiungo tutte le superfici di lavoro + pCAvTlStm->SetSurfTm( *GetSurfTriMesh( vSurfLoc[0].Get())) ; + for ( int i = 1 ; i < int( vSurfLoc.size()) ; ++ i) + pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSurfLoc[i].Get())) ; + + // aggiungo le superfici di supporto + if ( ! vSurfSuppLoc.empty()) { + /* Se considero interamente la superficie di supporto ho diversi svantaggi : + 1) Incrementa notevolmente il Box complessivo delle superfici di lavoro + => Ho molti più punti nelle griglie di campionamento per Silhouette o percorsi di collisione + 2) Calcolo l'Offset di TriMesh di parti "lontane" dalla regione corrente di lavoro + => Più tempo computazionale per Offset + => Superfici con più triangoli + */ + // definisco una superficie di contenimento ; L'Offset verrà fatto solo sulle aprti di Stm interne ad essa + PtrOwner pStmContainment( CreateSurfTriMesh()) ; + if ( IsNull( pStmContainment)) + return false ; + if ( pSfrCnt != nullptr && pSfrCnt->IsValid() && abs( dDepth) > 10 * EPS_SMALL) { + // considero la regione complessiva di lavoro dell'utensile all'interno della quale non può uscire + double dOffs = m_TParams.m_dDiam / 2. + m_Params.m_dOverlap + SUPP_SURF_RADIAL_OFFS + 50 * EPS_SMALL ; + PtrOwner pSfrFreeMove( pSfrCnt->CreateOffsetSurf( dOffs, ICurve::OFF_FILLET)) ; + if ( IsNull( pSfrFreeMove) || ! pSfrFreeMove->IsValid()) + return false ; + // definisco una TriMesh di estrusione da questa regione + pSfrFreeMove->Translate( - dDepth * pSfrCnt->GetNormVersor()) ; + CICURVEPVECTOR vpCrv ; + for ( int nC = 0 ; nC < pSfrFreeMove->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pSfrFreeMove->GetLoopCount( nC) ; ++ nL) + vpCrv.emplace_back( pSfrFreeMove->GetLoop( nC, nL)) ; + } + pStmContainment.Set( GetSurfTriMeshByRegionExtrusion( vpCrv, ( dDepth + m_TParams.m_dLen) * pSfrCnt->GetNormVersor())) ; + } + + // definisco la tolleranza lineare per Offset + double dLinTol = 2. ; + // recupero le superfici singole ( più veloce che calcolare Offset complessivo) + for ( const SurfLocal& SurfSupp : vSurfSuppLoc) { + // le superfici di supporto devono essere ben definite ed avere un volume chiuso + const ISurfTriMesh* pStmSupp = GetSurfTriMesh( SurfSupp.Get()) ; + if ( pStmSupp == nullptr || ! pStmSupp->IsValid() || pStmSupp->GetTriangleCount() == 0 || + ! pStmSupp->IsClosed()) + continue ; + // tengo la la tengo la parte di superficie + PtrOwner pTruncStm( CloneSurfTriMesh( pStmSupp)) ; + if ( IsNull( pTruncStm) || ! pTruncStm->IsValid()) + return false ; + if ( ! IsNull( pStmContainment) && pStmContainment->IsValid() && + pStmContainment->GetTriangleCount() > 0 && pStmContainment->IsClosed()) { + PtrOwner pStmTemp( CloneSurfTriMesh( pTruncStm)) ; + if ( IsNull( pStmTemp) || ! pStmTemp->IsValid()) + return false ; + if ( pStmTemp->Intersect( *pStmContainment) && pStmTemp->IsClosed()) + pTruncStm.Set( Release( pStmTemp)) ; + } + // calcolo l'Offset + if ( ! IsNull( pTruncStm) && pTruncStm->IsValid()) { + PtrOwner pStmSuppOffs( CreateSurfTriMeshOffset( pTruncStm, SUPP_SURF_RADIAL_OFFS, dLinTol)) ; + if ( ! IsNull( pStmSuppOffs) && pStmSuppOffs->IsValid() && pStmSuppOffs->GetTriangleCount() > 0) + pCAvTlStm->AddSurfTm( *Release( pStmSuppOffs)) ; + } + } + } + + return true ; +} + +//--------------------------------------------------------------------------- +bool +SurfFinishing::EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& frSurf, const Vector3d& vtTool, + double dDepth, ISurfFlatRegion* pSfrCnt) +{ + // controllo dei parametri + if ( vSurfLoc.empty() || pSfrCnt == nullptr || ! pSfrCnt->IsValid()) + return true ; + + // calcolo silhouette dell'insieme di superfici + CISURFTMPVECTOR vpStm ; vpStm.reserve( vSurfLoc.size()) ; + for ( int i = 0 ; i < int( vSurfLoc.size()) ; ++ i) + vpStm.emplace_back( GetSurfTriMesh( vSurfLoc[i].Get())) ; + // determino il frame locale delle superfici analizzando la prima + Frame3d frPocket ; + Point3d ptCen ; pSfrCnt->GetCentroid( ptCen) ; + frPocket.Set( ptCen, vtTool) ; + frPocket.ToLoc( frSurf) ; + const double SILH_TOL = 1. ; + PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; + if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( vpStm, frPocket, SILH_TOL)) + return false ; + POLYLINEVECTOR vPL ; + if ( ! pCavParSilh->GetSilhouette( - dDepth, vPL)) + return false ; + // creazione della regione piana dalle PolyLine ricavate dalla Silhouette + const double SILH_ARC_TOL = SILH_TOL / 10. ; + const double SILH_ARC_FEA_MAX = 100. ; + SurfFlatRegionByContours SfrMaker ; + for ( auto& PL : vPL) { + // recupero la curva dalla silhouette + PtrOwner pSilCrv( CreateCurveComposite()) ; + if ( IsNull( pSilCrv)) + return false ; + pSilCrv->FromPolyLine( PL) ; + // approssimo con archi + PolyArc PA ; + if ( pSilCrv->ApproxWithArcsEx( SILH_ARC_TOL, ANG_TOL_STD_DEG, SILH_ARC_FEA_MAX, PA)) { + PtrOwner pTempCrv( CreateCurveComposite()) ; + if ( ! IsNull( pTempCrv) && + pTempCrv->FromPolyArc( PA) && + pTempCrv->RemoveSmallDefects( SILH_ARC_TOL / 2., ANG_TOL_STD_DEG) && + pTempCrv->MergeCurves( SILH_ARC_TOL / 2., ANG_TOL_STD_DEG)) + pSilCrv.Set( pTempCrv) ; + } + // aggiungo per regione + if ( ! SfrMaker.AddCurve( Release( pSilCrv))) + return false ; + } + PtrOwner pSfrSil( SfrMaker.GetSurf()) ; + if ( ! IsNull( pSfrSil)) { + pSfrSil->ToGlob( frSurf) ; + double dPockRadOffs = SILH_ARC_TOL ; + pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ; + // intersezione tra contorno e regione + if ( ! pSfrCnt->Intersect( *pSfrSil)) { + // ricreo la regione originale + PtrOwner pSfrCntCopy( CloneSurfFlatRegion( pSfrCnt)) ; + if ( IsNull( pSfrCntCopy) || ! pSfrCntCopy->IsValid()) + return false ; + pSfrCnt->Clear() ; + pSfrCnt->CopyFrom( pSfrCntCopy) ; + } + // azzero le proprietà delle curve semplici dei contorni delle regioni ( se 1 lato aperto) + for ( int nC = 0 ; nC < pSfrCnt->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pSfrCnt->GetLoopCount( nC) ; ++ nL) { + for ( int nCrv = 0 ; ; ++ nCrv) { + if ( ! pSfrCnt->SetCurveTempProp( nC, nL, nCrv, TEMP_PROP_CLOSE_EDGE, 0) || + ! pSfrCnt->SetCurveTempProp( nC, nL, nCrv, TEMP_PROP_CLOSE_EDGE, 1)) + break ; + } + } + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId) @@ -1317,13 +1524,9 @@ SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3108, "Error in SurfFinishing : Depth not computable") ; return false ; } - - // recupero il box del grezzo in globale - BBox3d b3Raw ; - if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) { - m_pMchMgr->SetLastError( 3107, "Error in SurfFinishing : Empty RawBox") ; - return false ; - } + // se spessore positivo, lo sottraggo al risultato + if ( dThick > 0) + dDepth -= dThick ; // verifico che la curva sia piana Plane3d plPlane ; @@ -1351,56 +1554,20 @@ SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId) // verifico se archi vanno approssimati con segmenti di retta bool bSplitArcs = GetSplitArcs( vtTool) ; - // porto tutte le superfici nel riferimento della prima + // recupero le superfici di lavoro e di supporto + SURFLOCALVECTOR vSrfLoc, vSrfLocSupp ; Frame3d frSurf ; - SURFLOCALVECTOR vSrfLoc ; - INTVECTOR vSurfId ; - GetActiveSurfaces( vSurfId) ; - for ( auto nSurfId : vSurfId) { - if ( vSrfLoc.empty()) { - if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf)) - return false ; - } - vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ; - } - if ( ! frSurf.IsValid()) { + if ( ! GetSurfacesByIds( vSrfLoc, vSrfLocSupp, frSurf)) { m_pMchMgr->SetLastError( 3123, "Error in SurfFinishing : missing surfaces") ; return false ; } - // predispongo l'ambiente di correzione dei percorsi utensili con le superfici attive dei pezzi + // predispongo l'ambiente di correzione dei percorsi utensili PtrOwner pCAvTlStm( CreateCAvToolSurfTm()) ; - if ( IsNull( pCAvTlStm)) + if ( IsNull( pCAvTlStm) || ! SetCAvTlStmForSurfaces( pCAvTlStm, nullptr, dDepth, vSrfLoc, vSrfLocSupp)) { + m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; 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 dDeltaRad ; - double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ; - if ( m_TParams.m_dSideAng > 0) { - if ( m_TParams.m_dCornRad < EPS_SMALL) - dDeltaRad = m_TParams.m_dMaxMat * tan( dSideAngRad) ; - else - dDeltaRad = m_TParams.m_dCornRad * cos( dSideAngRad) + - ( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad) ; - } - else { - dDeltaRad = tan( dSideAngRad) * m_TParams.m_dMaxMat ; - } - double dStemRad = m_TParams.m_dDiam / 2 + dDeltaRad ; - 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()) ; - } - pCAvTlStm->SetSurfTm( *GetSurfTriMesh( vSrfLoc[0].Get())) ; - for ( int i = 1 ; i < int( vSrfLoc.size()) ; ++ i) - pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc[i].Get())) ; // assegno il vettore estrazione al gruppo del percorso m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; @@ -1409,11 +1576,6 @@ SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId) SetPathId( nPxId) ; SetToolDir( vtTool) ; - // recupero la curva da lavorare - PtrOwner pCrvCompo( pCrvCompoGDB->Clone()) ; - if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid()) - return false ; - // Eseguo la lavorazione a seconda del tipo double dElev = dDepth ; @@ -1485,13 +1647,6 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId) if ( dThick > 0) dDepth -= dThick ; - // recupero il box del grezzo in globale - BBox3d b3Raw ; - if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) { - m_pMchMgr->SetLastError( 3107, "Error in SurfFinishing : Empty RawBox") ; - return false ; - } - // recupero il Loop esterno della regione da svuotatare PtrOwner pCrvExt( pSfrGDB->GetLoop( 0, 0)) ; if ( IsNull( pCrvExt) || ! pCrvExt->IsValid()) @@ -1509,12 +1664,6 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId) } if ( plPlane.GetVersN() * vtExtr * dArea < 0) pCrvExt->Invert() ; - if ( plPlane.GetVersN() * vtExtr < 0) - plPlane.Invert() ; - - // recupero flag per saltare parti a massimo affondamento - bool bSkipMaxDown = true ; - GetValInNotes( m_Params.m_sUserNotes, "SkipMaxDown", bSkipMaxDown) ; // recupero nome del path string sPathName ; @@ -1535,57 +1684,14 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId) // verifico se archi vanno approssimati con segmenti di retta bool bSplitArcs = GetSplitArcs( vtTool) ; - // porto tutte le superfici nel riferimento della prima + // recupero le superfici di lavoro e di supporto + SURFLOCALVECTOR vSrfLoc, vSrfLocSupp ; Frame3d frSurf ; - SURFLOCALVECTOR vSrfLoc ; - INTVECTOR vSurfId ; - GetActiveSurfaces( vSurfId) ; - for ( auto nSurfId : vSurfId) { - if ( vSrfLoc.empty()) { - if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf)) - return false ; - } - vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ; - } - if ( ! frSurf.IsValid()) { + if ( ! GetSurfacesByIds( vSrfLoc, vSrfLocSupp, frSurf)) { m_pMchMgr->SetLastError( 3123, "Error in SurfFinishing : missing surfaces") ; return false ; } - // 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 dDeltaRad ; - double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ; - if ( m_TParams.m_dSideAng > 0) { - if ( m_TParams.m_dCornRad < EPS_SMALL) - dDeltaRad = m_TParams.m_dMaxMat * tan( dSideAngRad) ; - else - dDeltaRad = m_TParams.m_dCornRad * cos( dSideAngRad) + - ( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad) ; - } - else { - dDeltaRad = tan( dSideAngRad) * m_TParams.m_dMaxMat ; - } - double dStemRad = m_TParams.m_dDiam / 2 + dDeltaRad ; - 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()) ; - } - pCAvTlStm->SetSurfTm( *GetSurfTriMesh( vSrfLoc[0].Get())) ; - for ( int i = 1 ; i < int( vSrfLoc.size()) ; ++ i) - pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc[i].Get())) ; - // determino la regione da lavorare PtrOwner pSfrCnt( CreateSurfFlatRegion()) ; if ( IsNull( pSfrCnt) || ! pSfrCnt->AddExtLoop( *pCrvExt)) { @@ -1596,81 +1702,54 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId) // recupero l'isola PtrOwner pCrvIsl( pSfrGDB->GetLoop( 0, nL)) ; if ( IsNull( pCrvIsl) || ! pCrvIsl->IsValid() || - ! pSfrCnt->AddIntLoop( Release( pCrvIsl))) - return false ; - } - - // se richiesto, elimino le parti al massimo affondamento - if ( bSkipMaxDown) { - // calcolo silhouette dell'insieme di superfici - CISURFTMPVECTOR vpStm ; vpStm.reserve( vSurfId.size()) ; - for ( int i = 0 ; i < int( vSrfLoc.size()) ; ++ i) - vpStm.emplace_back( GetSurfTriMesh( vSrfLoc[i].Get())) ; - Frame3d frPocket ; - Point3d ptCen ; pCrvExt->GetCentroid( ptCen) ; - frPocket.Set( ptCen, vtTool) ; - frPocket.ToLoc( frSurf) ; - const double SILH_TOL = 1.0 ; - PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; - if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( vpStm, frPocket, SILH_TOL)) - return false ; - POLYLINEVECTOR vPL ; - if ( ! pCavParSilh->GetSilhouette( -dDepth, vPL)) { + ! pSfrCnt->AddIntLoop( Release( pCrvIsl))) { m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; return false ; } - // creo la regione piana dalle PolyLine ricavate dalla Silhouette - const double SILH_ARC_TOL = 0.1 * SILH_TOL ; - const double SILH_ARC_FEA_MAX = 100. ; - SurfFlatRegionByContours SfrMaker ; - for ( auto& PL : vPL) { - // recupero la curva dalla silhouette - PtrOwner pSilCrv( CreateCurveComposite()) ; - if ( IsNull( pSilCrv)) - return false ; - pSilCrv->FromPolyLine( PL) ; - // approssimo con archi - PolyArc PA ; - if ( pSilCrv->ApproxWithArcsEx( SILH_ARC_TOL, ANG_TOL_STD_DEG, SILH_ARC_FEA_MAX, PA)) { - PtrOwner pTempCrv( CreateCurveComposite()) ; - if ( ! IsNull( pTempCrv) && - pTempCrv->FromPolyArc( PA) && - pTempCrv->RemoveSmallDefects( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG) && - pTempCrv->MergeCurves( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG)) - pSilCrv.Set( pTempCrv) ; - } - // aggiungo per regione - if ( ! SfrMaker.AddCurve( Release( pSilCrv))) { - m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; - return false ; - } - } - PtrOwner pSfrSil( SfrMaker.GetSurf()) ; - if ( ! IsNull( pSfrSil)) { - pSfrSil->ToGlob( frSurf) ; - double dPockRadOffs = SILH_ARC_TOL ; - pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ; - // intersezione tra contorno e regione - if ( ! pSfrCnt->Intersect( *pSfrSil)) { - // ricreo la regione originale - pSfrCnt->Clear() ; - pSfrCnt->AddExtLoop( *pCrvExt) ; - } - // azzero le proprietà delle curve semplici dei contorni delle regioni ( se 1 lato aperto) - for ( int nC = 0 ; nC < pSfrCnt->GetChunkCount() ; ++ nC) { - for ( int nL = 0 ; nL < pSfrCnt->GetLoopCount( nC) ; ++ nL) { - for ( int nCrv = 0 ; ; ++ nCrv) { - if ( ! pSfrCnt->SetCurveTempProp( nC, nL, nCrv, 0, 0) || - ! pSfrCnt->SetCurveTempProp( nC, nL, nCrv, 0, 1)) - break ; - } - } - } + } + // se regione non valida, non faccio nulla + if ( ! pSfrCnt->IsValid()) + return true ; + #if DEBUG_SFR + int nGrp = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + m_pGeomDB->SetName( nGrp, "FlatRegions") ; + int nLay = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLay, "Sfr_by_curves") ; + int nSfr = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay, pSfrCnt->Clone()) ; + m_pGeomDB->SetMaterial( nSfr, Color( 0., 1., 0., .5)) ; + #endif + + // predispongo l'ambiente di correzione dei percorsi utensili + PtrOwner pCAvTlStm( CreateCAvToolSurfTm()) ; + PtrOwner pSfrCntLoc( CloneSurfFlatRegion( pSfrCnt)) ; + if ( IsNull( pCAvTlStm) || + IsNull( pSfrCntLoc) || ! pSfrCntLoc->IsValid() || ! pSfrCntLoc->ToLoc( frSurf) || + ! SetCAvTlStmForSurfaces( pCAvTlStm, pSfrCntLoc, dDepth, vSrfLoc, vSrfLocSupp)) { + m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; + return false ; + } + + // se richiesto, elimino le parti al massimo affondamento + bool bSkipMaxDown = true ; + GetValInNotes( m_Params.m_sUserNotes, "SkipMaxDown", bSkipMaxDown) ; + PerformanceCounter PC ; + PC.Start() ; + if ( bSkipMaxDown) { + if ( ! EraseMaxDownSurf( vSrfLoc, frSurf, vtTool, dDepth, pSfrCnt)) { + m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; + return false ; } } + LOG_INFO( GetEMkLogger(), ( "ToT Time : " + ToString( PC.Stop())).c_str()) ; // se regione risultante vuota, non devo fare altro if ( ! pSfrCnt->IsValid()) return true ; + #if DEBUG_SFR + int nLay3 = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrp, GLOB_FRM) ; + m_pGeomDB->SetName( nLay3, "Sfr_Final") ; + int nSfrF = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nLay3, pSfrCnt->Clone()) ; + m_pGeomDB->SetMaterial( nSfrF, LIME) ; + #endif // assegno il vettore estrazione al gruppo del percorso m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; @@ -1679,9 +1758,12 @@ SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId) SetPathId( nPxId) ; SetToolDir( vtTool) ; + // inserisco le superfici di supporto tra le superfici locali + for ( SurfLocal& SurfLocSupp : vSrfLocSupp) + vSrfLoc.emplace_back( SurfLocSupp) ; + // Eseguo la lavorazione a seconda del tipo double dElev = dDepth ; - switch ( m_Params.m_nSubType) { case SURFFIN_SUB_ZIGZAG : if ( ! AddZigZag( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs)) @@ -1759,10 +1841,17 @@ SurfFinishing::SimplifyCurve( ICurveComposite* pCompo) const //---------------------------------------------------------------------------- bool -SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId) const +SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId, INTVECTOR& vSurfSuppId) const { + // NB. + // - vSrufInd contiene gli Id delle superfici selezionate ( nel caso non ci siano superfici + // seleionate, allora vengono considerate tutte le superfici presenti nei grezzi attivi della fase + // - vSurfSupp contiene gli Id delle superfici di supporto, quindi quelle superici da cui si vuole + // mantenere una certa distanza con l'utensile ( senza che siano selezionate) + // pulisco vettore superfici vSurfId.clear() ; + vSurfSuppId.clear() ; // verifiche if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr) return false ; @@ -1772,10 +1861,9 @@ SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId) const if ( m_pGeomDB->GetGeoType( nEntId) == SRF_TRIMESH) vSurfId.emplace_back( nEntId) ; } - // se trovate superfici, considero solo queste ed esco - if ( ! vSurfId.empty()) - return true ; - // altrimenti considero tutte le superfici dei pezzi nei grezzi attivi della fase + // controllo se sono state trovate delle superfici + bool bNoSurfId = ( vSurfId.empty()) ; + // scorro tutte le superfici dei pezzi nei grezzi attivi della fase int nRawId = m_pMchMgr->GetFirstRawPart() ; while ( nRawId != GDB_ID_NULL) { if ( m_pMchMgr->VerifyRawPartPhase(nRawId, m_nPhase)) { @@ -1791,18 +1879,26 @@ SurfFinishing::GetActiveSurfaces( INTVECTOR& vSurfId) const // se entità superficie e visibile, la aggiungo int nStat ; if ( m_pGeomDB->GetGeoType( nEntId) == SRF_TRIMESH && - m_pGeomDB->GetCalcStatus( nEntId, nStat) && nStat != GDB_ST_OFF) - vSurfId.emplace_back( nEntId) ; + m_pGeomDB->GetCalcStatus( nEntId, nStat) && nStat != GDB_ST_OFF) { + // se non sono state selezionate superfici precedentemente, memorizzo tale id + if ( bNoSurfId) + vSurfId.emplace_back( nEntId) ; + // verifico se è presente una superficie di controllo + string sLayIdName ; + if ( m_pGeomDB->GetName( nLayId, sLayIdName) && EqualNoCase( sLayIdName, SRF_SUPP_LAYER_NAME)) + vSurfSuppId.emplace_back( nEntId) ; + } // passo alla entità successiva nEntId = m_pGeomDB->GetNext( nEntId) ; } - nLayId =m_pGeomDB->GetNextGroup( nLayId) ; + nLayId = m_pGeomDB->GetNextGroup( nLayId) ; } nPartId = m_pMchMgr->GetNextPartInRawPart( nPartId) ; } } nRawId = m_pMchMgr->GetNextRawPart( nRawId) ; } + return true ; } @@ -5472,7 +5568,7 @@ SurfFinishing::GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) con double SurfFinishing::GetRadiusForStartEndElevation( void) const { - const double DELTA_ELEV_RAD = 4.0 ; + const double DELTA_ELEV_RAD = 4.0 ; double dDeltaRad = min( DELTA_ELEV_RAD, 0.5 * m_TParams.m_dTDiam) ; return ( 0.5 * m_TParams.m_dTDiam + dDeltaRad) ; } diff --git a/SurfFinishing.h b/SurfFinishing.h index 8a911e3..877600a 100644 --- a/SurfFinishing.h +++ b/SurfFinishing.h @@ -104,8 +104,13 @@ class SurfFinishing : public Machining bool VerifyGeometry( SelData Id, int& nSubs) ; bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ; bool Chain( int nGrpDestId) ; - bool ProcessSfr( int nPathId, int nPvId, int nClId) ; + bool GetSurfacesByIds( SURFLOCALVECTOR& vSrfLoc, SURFLOCALVECTOR& vSrfSuppLoc, Frame3d& frSurf) ; + bool SetCAvTlStmForSurfaces( ICAvToolSurfTm* pCAvTlStm, const ISurfFlatRegion* pSfrCnt, double dDepth, + SURFLOCALVECTOR& vSurfLoc, SURFLOCALVECTOR& vSurfSuppLoc) ; + bool EraseMaxDownSurf( const SURFLOCALVECTOR& vSurfLoc, const Frame3d& frSurf, const Vector3d& vtTool, + double dDepth, ISurfFlatRegion* pSfrCnt) ; bool ProcessCrvCompo( int nPathId, int nPvId, int nClId) ; + bool ProcessSfr( int nPathId, int nPvId, int nClId) ; bool SimplifyCurve( ICurveComposite* pCompo) const ; bool CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frPocket, const Frame3d& frSurf, const Vector3d& vtTool, double dDepth, @@ -158,7 +163,7 @@ class SurfFinishing : public Machining const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtTool, Point3d& ptP1) const ; bool GetSurfaceNormalAtPoint( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const Point3d& ptTool, const Vector3d& vtTool, Vector3d& vtNorm) const ; - bool GetActiveSurfaces( INTVECTOR& vSurfId) const ; + bool GetActiveSurfaces( INTVECTOR& vSurfId, INTVECTOR& vSurfSuppId) const ; int ProcessSquare( int nFlag, double dLevel, double dQPt0, double dQpt1, double dQpt2, double dQpt3, int& nI1s, int& nI1e, int& nI2s, int& nI2e) const ; Point3d CalcShapedPoint( const PNTUVVECT& myInfoStart, const PNTUVVECT& myInfoEnd, bool bSpiral, const Vector3d& vtAxL,