From 7a864d95034b894ba832ff41e0f5e775389293dd Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Fri, 10 Jan 2025 16:43:59 +0100 Subject: [PATCH] EgtMachKernel : - in Sgrossature migliorate le gestioni delle Silhouette rispettando la geometria del Tool - In Finiture, migliorati i controlli per finiture ZConst. --- SurfFinishing.cpp | 116 ++++++++++++++++++++++++++++--------------- SurfRoughing.cpp | 124 ++++++++++++++++++++++++++++++++++++++-------- SurfRoughing.h | 4 +- 3 files changed, 181 insertions(+), 63 deletions(-) diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 6971f0e..8679ca2 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -87,6 +87,7 @@ static string KEY_THICK = "THICK" ; const double SILH_SAMPLING = 1. ; #define ENABLE_ZCONST_DEBUG 0 +#define ENABLE_OPTIMAL_DEBUG 0 //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_SURFFINISHING), SurfFinishing) ; @@ -2171,6 +2172,12 @@ SurfFinishing::GetZConstFacesInsideSfr( const SURFLOCALVECTOR& vSrfLoc, const Fr PtrOwner pSfrLoc( CloneSurfFlatRegion( pSfr)) ; if ( IsNull( pSfrLoc) || ! pSfrLoc->IsValid() || ! pSfrLoc->ToLoc( frSfr)) return false ; + // recupero le curve della regione + ICRVCOMPOPOVECTOR vCrvSfrLoc ; + for ( int nC = 0 ; nC < pSfrLoc->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pSfrLoc->GetLoopCount( nC) ; ++ nL) + vCrvSfrLoc.emplace_back( ConvertCurveToComposite( pSfrLoc->GetLoop( nC, nL))) ; + } // scorro le superfici trimesh selezionate for ( int nS = 0 ; nS < int( vSrfLoc.size()) ; ++ nS) { @@ -2189,31 +2196,37 @@ SurfFinishing::GetZConstFacesInsideSfr( const SURFLOCALVECTOR& vSrfLoc, const Fr // recupero i contorni della faccia POLYLINEVECTOR vPL ; if ( pStm->GetFacetLoops( nF, vPL)) { - // recupero la superficie piana dalle curve - SurfFlatRegionByContours SfrByC ; for ( int nPL = 0 ; nPL < int( vPL.size()) ; ++ nPL) { + // recupero il bordo della PolyLine PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( vPL[nPL])) return false ; + // se curva trascurabile, passo alla successiva + double dMaxOffs ; + if ( ! CalcCurveLimitOffset( *pCrvCompo, dMaxOffs)) + return false ; + if ( dMaxOffs < 1.5 * m_TParams.m_dTDiam) + continue ; // porto la curva nel riferimento globale pCrvCompo->ToGlob( frSurf) ; // porto la curva nel riferimento della pSfr (per la classificazione) pCrvCompo->ToLoc( frSfr) ; - // aggiungo la curva alla FlatRegion - SfrByC.AddCurve( Release( pCrvCompo)) ; - } - // recupero la superficie - PtrOwner pSfrFace( SfrByC.GetSurf()) ; - if ( IsNull( pSfrFace) || ! pSfrFace->IsValid()) - return false ; - // se esiste intersezione tra pSfrFace e pSfr allora salvo la Z locale - pSfrFace->Intersect( *pSfrLoc) ; - if ( ! IsNull( pSfrFace) && pSfrFace->IsValid()) { - // porto il punto nel riferimento della superficie - ptCenter.ToGlob( frSurf) ; - ptCenter.ToLoc( frSfr) ; - // inserisco la Z del piano locale nell'insieme - setZAmbiguos.insert( ptCenter.z) ; + // translo la curva a contatto con la pSfr + Point3d ptS ; vPL[nPL].GetFirstPoint( ptS) ; + pCrvCompo->Translate( ( - ptS.z) * Z_AX) ; + // controllo l'intersezione + bool bInters = false ; + for ( int i = 0 ; i < int( vCrvSfrLoc.size()) && ! bInters ; ++ i) { + IntersCurveCurve ICC( *vCrvSfrLoc[i], *pCrvCompo) ; + bInters = ( ICC.GetIntersCount() > 0) ; + } + if ( bInters) { + // porto il punto nel riferimento della superficie + ptCenter.ToGlob( frSurf) ; + ptCenter.ToLoc( frSfr) ; + // inserisco la Z del piano locale nell'insieme + setZAmbiguos.insert( ptCenter.z) ; + } } } } @@ -2699,6 +2712,12 @@ SurfFinishing::CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d PL.EraseLastUPoint() ; PL.AddUPoint( 0, ptStart_forced, false) ; PL.AddUPoint( PL.GetPointNbr(), ptEnd_forced, true) ; + // controllo di non essere sceso oltre la depth (il link non per forza è vicino ad una curva di livello) + PNTULIST& myPtUList = PL.GetUPointList() ; + for ( POINTU& myPtU : myPtUList) { + if ( myPtU.first.z < - dDepth) + myPtU.first.z = - dDepth ; + } // creo una curva composita a partire dalla polilinea PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) @@ -2734,7 +2753,10 @@ SurfFinishing::AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf return false ; } // se non ho curve, esco - if ( vCrvCompo.empty()) + bool bNoCrv = true ; + for ( int i = 0 ; i < int( vCrvCompo.size()) && bNoCrv ; ++ i) + bNoCrv = ( vCrvCompo[i].empty()) ; + if ( bNoCrv) return true ; // collego tra loro le curve trovate @@ -3220,8 +3242,10 @@ SurfFinishing::SplitStmInTwoSilSfrByClippingAngle( const SURFLOCALVECTOR& vSrfLo while ( ! IsNull( pStmCurr) && pStmCurr->IsValid() && pStmCurr->GetTriangleCount() > 0) { // porto la superficie nel sistema di riferimento globale pStmCurr->ToGlob( frSurf) ; - int _o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmCurr->Clone()) ; - m_pGeomDB->SetMaterial( _o, PURPLE) ; + #if ENABLE_OPTIMAL_DEBUG + int _o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pStmCurr->Clone()) ; + m_pGeomDB->SetMaterial( _o, PURPLE) ; + #endif vStmLocZConst.emplace_back( Release( pStmCurr)) ; pStmCurr.Set( StmSoup.GetSurf()) ; } ; @@ -3259,11 +3283,13 @@ SurfFinishing::SplitStmInTwoSilSfrByClippingAngle( const SURFLOCALVECTOR& vSrfLo } } - int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrSpiral->Clone()) ; - m_pGeomDB->SetMaterial( _a, Color( 255., 0., 255., .25)) ; - _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrZConst->Clone()) ; - m_pGeomDB->SetMaterial( _a, Color( 0., 255., 0., .25)) ; - LOG_ERROR( GetEMkLogger(), ToString( dMaxRad).c_str()) ; + #if ENABLE_OPTIMAL_DEBUG + int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrSpiral->Clone()) ; + m_pGeomDB->SetMaterial( _a, Color( 255., 0., 255., .25)) ; + _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrZConst->Clone()) ; + m_pGeomDB->SetMaterial( _a, Color( 0., 255., 0., .25)) ; + LOG_ERROR( GetEMkLogger(), ToString( dMaxRad).c_str()) ; + #endif // elimino i piccoli chunk imprecisi for ( int nC = 0 ; nC < pSfrSpiral->GetChunkCount() ; ++ nC) { @@ -3419,7 +3445,7 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr VECTORPATHS vPaths ; // definizione angolo di tolleranza per lavorazioni Spiral e ZConst - double dClippingAngle = ANG_TOL_STD_DEG * 3. ; + double dClippingAngle = 3. * ANG_TOL_STD_DEG ; PtrOwner pSfrSpiral( CreateSurfFlatRegion()) ; PtrOwner pSfrZConst( CreateSurfFlatRegion()) ; if ( ! SplitStmInTwoSilSfrByClippingAngle( vSrfLoc, frSurf, pSfr, dDepth, vtTool, dClippingAngle, pSfrSpiral, pSfrZConst)) @@ -3434,10 +3460,12 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr // mi assicuro di non uscire dalla superficie originale pSfrToWork->Intersect( *pSfr) ; // assegno tutte proprietà di lato chiuso - for ( int nC = 0 ; nC < pSfrToWork->GetChunkCount() ; ++ nC) - for ( int nL = 0 ; nL < pSfrToWork->GetLoopCount( nC) ; ++ nL) + for ( int nC = 0 ; nC < pSfrToWork->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pSfrToWork->GetLoopCount( nC) ; ++ nL) { for ( int nU = 0 ; nU < pSfrToWork->GetLoopCurveCount( nC, nL) ; ++ nU) pSfrToWork->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ; + } + } // lavorazione Spiral/ZigZag ICRVCOMPOPOVECTOR vpCrvs ; if ( ! CalcPocketing( pSfrToWork, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, @@ -3498,12 +3526,14 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr for ( int i = 0 ; i < int( vPaths.size()) ; ++ i) vPaths[i].pCrvPath->ToGlob( frPocket) ; } - // disegno i percorsi per controllo - int ___a = int( vPaths.size()) ; - for ( int i = 0 ; i < int( vPaths.size()) ; ++ i) { - int _n = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vPaths[i].pCrvPath->Clone()) ; - m_pGeomDB->SetMaterial( _n, RED) ; - } + #if ENABLE_OPTIMAL_DEBUG + // disegno i percorsi per controllo + int ___a = int( vPaths.size()) ; + for ( int i = 0 ; i < int( vPaths.size()) ; ++ i) { + int _n = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vPaths[i].pCrvPath->Clone()) ; + m_pGeomDB->SetMaterial( _n, RED) ; + } + #endif // ----------------------- Lavorazione Zconst ------------------------------- if ( ! IsNull( pSfrZConst) && pSfrZConst->IsValid()) { @@ -3514,10 +3544,12 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr // mi assicuro di non uscire dalla superficie originale pSfrToWork->Intersect( *pSfr) ; // assegno tutte proprietà di lato chiuso - for ( int nC = 0 ; nC < pSfrToWork->GetChunkCount() ; ++ nC) - for ( int nL = 0 ; nL < pSfrToWork->GetLoopCount( nC) ; ++ nL) + for ( int nC = 0 ; nC < pSfrToWork->GetChunkCount() ; ++ nC) { + for ( int nL = 0 ; nL < pSfrToWork->GetLoopCount( nC) ; ++ nL) { for ( int nU = 0 ; nU < pSfrToWork->GetLoopCurveCount( nC, nL) ; ++ nU) pSfrToWork->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ; + } + } // inizializzo la classe di calcolo delle silhouette nei piani come sopra PtrOwner pCavParSilh( GetParSilhouettesForZConst( vSrfLoc, frSurf, pSfrToWork)) ; if ( IsNull( pCavParSilh)) @@ -3545,11 +3577,13 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr } } - // disegno i percorsi per controllo - for ( int i = ___a ; i < int( vPaths.size()) ; ++ i) { - int _n = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vPaths[i].pCrvPath->Clone()) ; - m_pGeomDB->SetMaterial( _n, GREEN) ; - } + #if ENABLE_OPTIMAL_DEBUG + // disegno i percorsi per controllo + for ( int i = ___a ; i < int( vPaths.size()) ; ++ i) { + int _n = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vPaths[i].pCrvPath->Clone()) ; + m_pGeomDB->SetMaterial( _n, GREEN) ; + } + #endif // ordino i percorsi in base alla Zlocale if ( ! OrderOptimalPathsByZLoc( pSfr, vPaths)) diff --git a/SurfRoughing.cpp b/SurfRoughing.cpp index 50f11ee..0a48eee 100644 --- a/SurfRoughing.cpp +++ b/SurfRoughing.cpp @@ -94,6 +94,7 @@ static string KEY_OPEN = "OPEN" ; static string KEY_THICK = "THICK" ; #define ENABLE_DEBUG_SFR 0 +#define ENABLE_DEBUG_STM_NORMAL_SHADER 0 #define ENABLE_DEBUG_FEEDS 0 #define ENABLE_DEBUG_SFR_BOOLEANS 0 #define ENABLE_DEBUG_ZPLANE 0 @@ -254,7 +255,7 @@ SurfRoughing::SurfRoughing( void) m_nPaths = 0 ; m_dMaxHelixRad = INFINITO ; m_dSubStepToler = 2.0 / 2 ; - m_dStepToler = 1.0 / 1 ; + m_dStepToler = 1.0 / 2 ; m_bDetectPlaneZ = false ; } @@ -1345,8 +1346,12 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) if ( vSurfL[i].Get() == nullptr) return false ; const ISurfTriMesh* pStm = GetSurfTriMesh( vSurfL[i].Get()) ; - if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0) + if ( pStm != nullptr && pStm->IsValid() && pStm->GetTriangleCount() > 0) { vpStm.emplace_back( pStm) ; + #if ENABLE_DEBUG_STM_NORMAL_SHADER + DrawNormalShaderSurfTm( vpStm.back(), ToString( i)) ; + #endif + } } const double SILH_TOL = 1.0 ; PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; @@ -1486,6 +1491,11 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) else continue ; // step fuori dal grezzo, passo al successivo + // definisco la regione rimossa temporanea + PtrOwner pSfrRemoved_tmp( CloneSurfFlatRegion( pSfr)) ; + if ( IsNull( pSfrRemoved_tmp)) + return false ; + /* ***************** Regione piana esterna a pCompo ****************** */ PtrOwner pSfrOutCompo( CreateSurfFlatRegion()) ; if ( IsNull( pSfrOutCompo)) @@ -1502,6 +1512,9 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) // determino la regione da non lavorare e la sottraggo double dSilDepth = it->dDepth - ( it->bPlaneZStep ? SIL_DEPTH_TOL : 0.) ; bool bOkSil = false ; + PtrOwner pSfrSil_Hypothetical( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrSil_Hypothetical)) + return false ; PtrOwner pSfrSil( GetSfrSilhouette( pCavParSilh, dSilDepth, SILH_TOL, bOkSil)) ; if ( ! bOkSil) { m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ; @@ -1509,6 +1522,7 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) } if ( ! IsNull( pSfrSil) && ! it->bPlaneZStep) { pSfrSil->Offset( GetOffsR(), ICurve::OFF_CHAMFER) ; // offset radiale sulla Silhouette + pSfrSil_Hypothetical.Set( CloneSurfFlatRegion( pSfrSil)) ; // regione di silhouette ipotetica pSfr->Subtract( *pSfrSil) ; // sottraggo le parti da non lavorare } if ( ! pSfr->IsValid() || pSfr->GetChunkCount() == 0) // se superficie non valida @@ -1516,7 +1530,13 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) // salvo la superficie rimossa delete( it->pSfrRemoved) ; - it->pSfrRemoved = CloneSurfFlatRegion( pSfr) ; + it->pSfrRemoved = CloneSurfFlatRegion( pSfrRemoved_tmp) ; + if ( pSfrSil_Hypothetical->IsValid() && pSfrSil_Hypothetical->GetChunkCount() > 0) { + pSfrSil_Hypothetical->Offset( m_TParams.m_dDiam / 2, ICurve::OFF_FILLET) ; // si può ingrandire leggermente (più conservativo) + pSfrSil_Hypothetical->Offset( - m_TParams.m_dDiam / 2, ICurve::OFF_FILLET) ; + // la silhouette ipotetica ora ha i lati chiusi definiti dal rotalamento del tool lungo il chiuso reale + it->pSfrRemoved->Subtract( *pSfrSil_Hypothetical) ; // la rimossa dipende dalla silhouette ipotetica (non quella reale) + } // se PlaneZ if ( it->bPlaneZStep && ! IsNull( pSfrSil) && pSfrSil->IsValid()) { pSfrSil->Offset( GetOffsR(), ICurve::OFF_CHAMFER) ; // offset radiale sulla Silhouette @@ -1602,9 +1622,22 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) } // se regione risultante non vuota if ( pSfr->IsValid() && pSfr->GetChunkCount() > 0) { + // *************************** Regione Limite *************************** + PtrOwner pSfrLimit( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrLimit)) + return false ; + if ( ! IsNull( pSfrOutCompo) && pSfrOutCompo->IsValid()) + pSfrLimit.Set( pSfrOutCompo) ; + if ( ! IsNull( pSfrSil) && pSfrSil->IsValid()) { + if ( ! IsNull( pSfrLimit) && pSfrLimit->IsValid()) + pSfrLimit->Add( *pSfrSil) ; + else + pSfrLimit.Set( pSfrSil) ; + } + // se si tratta di un SottoStep, rimuovo tutti i chunk troppo snelli if ( it->bSubStep) { - if ( ! RemoveChunksUnderTolerance( pSfr, m_dSubStepToler, it->pSfrRemoved)) { + if ( ! RemoveChunksUnderTolerance( pSfr, m_dSubStepToler, pSfrLimit, it->pSfrRemoved)) { m_pMchMgr->SetLastError( 3029, "Error in SurfRoughing : Simplify Chunks for SubSteps failed") ; return false ; } @@ -1621,6 +1654,16 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3026, "Error in SurfRoughing : Detecting open edges failed") ; return false ; } + // se step base + if ( ! it->bSubStep && ! it->bPlaneZStep) { + RemoveChunksUnderTolerance( pSfr, m_dStepToler, pSfrLimit) ; + // se dopo la semplificazione non rimane nulla, allora passo allo step successivo + if ( ! pSfr->IsValid() || pSfr->GetChunkCount() == 0) { + delete( it->pSfrRemoved) ; // non ho rimosso nulla allo step corrente + it->pSfrRemoved = nullptr ; + continue ; + } + } // se si tratta di un SottoStep, chiudo tutti i lati aperti troppo corti if ( it->bSubStep) { @@ -1628,6 +1671,14 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3029, "Error in SurfRoughing : Simplify Chunks for SubSteps failed") ; return false ; } + // rimuovo tutti i Chunk snelli + RemoveChunksUnderTolerance( pSfr, m_dSubStepToler, pSfrLimit) ; + // se dopo la semplificazione non rimane nulla, allora passo allo step successivo + if ( ! pSfr->IsValid() || pSfr->GetChunkCount() == 0) { + delete( it->pSfrRemoved) ; // non ho rimosso nulla allo step corrente + it->pSfrRemoved = nullptr ; + continue ; + } } // salvo nella temp Prop della FlatRegion se si tratta di uno step base o extra @@ -1657,17 +1708,6 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId) // nel gruppo temporaneo salvo anche la superficie Limite) int nNew_SfrLimit_Id = GDB_ID_NULL ; - PtrOwner pSfrLimit( CreateSurfFlatRegion()) ; - if ( IsNull( pSfrLimit)) - return false ; - if ( ! IsNull( pSfrOutCompo) && pSfrOutCompo->IsValid()) - pSfrLimit.Set( pSfrOutCompo) ; - if ( ! IsNull( pSfrSil) && pSfrSil->IsValid()) { - if ( ! IsNull( pSfrLimit) && pSfrLimit->IsValid()) - pSfrLimit->Add( *pSfrSil) ; - else - pSfrLimit.Set( pSfrSil) ; - } if ( ! IsNull( pSfrLimit) && pSfrLimit->IsValid()) { nNew_SfrLimit_Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfrLimit)) ; if ( nNew_SfrLimit_Id == GDB_ID_NULL) { @@ -2076,7 +2116,6 @@ SurfRoughing::CalcPaths( const INTINTVECTOR& vPocket, STEPINFOSRVECTOR& vStepInf // scorro gli indici delle superfici int nInd = 0 ; for ( auto& vId : vPocket) { - // recupero la superficie da lavorare const ISurfFlatRegion* pSfrPock = GetSurfFlatRegion( m_pGeomDB->GetGeoObj( vId.first)) ; if ( pSfrPock == nullptr || ! pSfrPock->IsValid()) @@ -2103,7 +2142,10 @@ SurfRoughing::CalcPaths( const INTINTVECTOR& vPocket, STEPINFOSRVECTOR& vStepInf break ; } else if ( vStepInfo[nI].bIsExtraStep) { - vStepInfo[nInd].dRelativeDepth = vStepInfo[nInd].dDepth - vStepInfo[nI-1].dDepth ; // Depth relativa + if ( nI == 0) + vStepInfo[nInd].dRelativeDepth = vStepInfo[nInd].dDepth ; // Depth + else + vStepInfo[nInd].dRelativeDepth = vStepInfo[nInd].dDepth - vStepInfo[nI-1].dDepth ; // Depth relativa break ; } } @@ -2136,6 +2178,7 @@ SurfRoughing::CalcPaths( const INTINTVECTOR& vPocket, STEPINFOSRVECTOR& vStepInf if ( vStepInfo[nInd].bIsExtraStep) { string sWarn = "Warning in SurfRoughing : CalcPocketing failed with substep (" + ToString( vStepInfo[nInd].dDepth, 1) + ")" ; m_pMchMgr->SetWarning( 3055, sWarn) ; + vCrvPaths.clear() ; } else { m_pMchMgr->SetLastError( 3028, "Error in SurfRoughing : Error in CalcPocketing") ; @@ -2881,7 +2924,8 @@ SurfRoughing::SimplyfySfr( ISurfFlatRegion* pSfr) const //---------------------------------------------------------------------------- bool -SurfRoughing::RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr, double dTol, ISurfFlatRegion* pSfrToUpdate) const +SurfRoughing::RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr, double dTol, + ISurfFlatRegion* pSfrLimit, ISurfFlatRegion* pSfrToUpdate) const { /* quando si lavorano dei SubSteps, può capitare che la superfice da rimuovere sia molto snella; @@ -2902,6 +2946,10 @@ SurfRoughing::RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr, double dTol, IS if ( dTol < EPS_SMALL) // se tolleranza non presente, non faccio nulla return true ; + // se non ho superfici da non rovinare, allora non devo fare nulla (sarà tutto aperto) + if ( pSfrLimit == nullptr || ! pSfrLimit->IsValid() || pSfrLimit->GetChunkCount() == 0) + return true ; + // scorro tutti i chunk della superficie for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; ++ nC) { // verifico se l'Offset massimo del chunk è sopra alla tolleranza @@ -2909,6 +2957,22 @@ SurfRoughing::RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr, double dTol, IS pSfr->GetChunkMaxOffset( nC, dMaxOffs) ; // rimuovo il Chunk c-esimo se l'Offset massimo è minore della tolleranza if ( dMaxOffs < dTol) { + // devo evitare di rimuovere le isole aperte (queste, se rimosse, lasciano delle + // punte di materiale che non vengono rimossein quanto sempre scartate) + // piccolo Offset alla regione limite + double dOffs = m_TParams.m_dDiam / 2. + GetOffsR() + 30 * EPS_SMALL ; + PtrOwner pSfrLimitOffs( pSfrLimit->CreateOffsetSurf( dOffs, ICurve::OFF_FILLET)) ; + if ( IsNull( pSfrLimitOffs) || ! pSfrLimitOffs->IsValid()) + return false ; + // se il Chunk non tocca tale regione, allora lo conservo + PtrOwner pSfrChunk( pSfr->CloneChunk( nC)) ; + if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid()) + return false ; + pSfrChunk->Intersect( *pSfrLimitOffs) ; + if ( IsNull( pSfrChunk) || ! pSfrChunk->IsValid() || pSfrChunk->GetChunkCount() == 0) + continue ; + + // se ho una regione da aggiornare if ( pSfrToUpdate != nullptr && pSfrToUpdate->IsValid()) { PtrOwner pSfrChunk( pSfr->CloneChunk( nC)) ; if ( ! IsNull( pSfrChunk) || pSfrChunk->IsValid()) { @@ -3063,7 +3127,6 @@ SurfRoughing::CloseOpenEdgesUnderTolerance( ISurfFlatRegion* pSfr, double dToler } } - RemoveChunksUnderTolerance( pSfrRegular, m_dSubStepToler) ; // resituisco la superficie pSfr->CopyFrom( pSfrRegular) ; return true ; @@ -3218,8 +3281,6 @@ SurfRoughing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfFlatRegio } } - // per sicurezza - RemoveChunksUnderTolerance( pSfr, m_dStepToler) ; return true ; } @@ -3410,3 +3471,24 @@ SurfRoughing::DrawFeed( const ICurve* pCrv, double dFeed) return ; } + +//---------------------------------------------------------------------------- +void +SurfRoughing::DrawNormalShaderSurfTm( const ISurfTriMesh* pStm, string sName) +{ + if ( pStm == nullptr || ! pStm->IsValid()) + return ; + + int nIdGroup = m_pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, GLOB_FRM) ; + m_pGeomDB->SetName( nIdGroup, "ShaderStm") ; + int nIdLayer = m_pGeomDB->AddGroup( GDB_ID_NULL, nIdGroup, GLOB_FRM) ; + m_pGeomDB->SetName( nIdLayer, sName) ; + + for ( int nT = 0 ; nT < pStm->GetTriangleCount() ; ++ nT) { + PtrOwner pStmTria( pStm->CloneTriangle( nT)) ; + int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nIdLayer, pStmTria->Clone()) ; + Vector3d vtN ; pStmTria->GetFacetNormal( 0, vtN) ; + m_pGeomDB->SetMaterial( nId, Color( abs( vtN.x), abs( vtN.y), abs( vtN.z))) ; + } + return ; +} diff --git a/SurfRoughing.h b/SurfRoughing.h index f8a9489..2b6e398 100644 --- a/SurfRoughing.h +++ b/SurfRoughing.h @@ -129,7 +129,8 @@ class SurfRoughing : public Machining double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ; double GetRadiusForStartEndElevation( void) const ; bool ResetCurveAllTempProp( ICurve* pCurve) const ; - bool RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr, double dTol, ISurfFlatRegion* pSfrToUpdate = nullptr) const ; + bool RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr, double dTol, ISurfFlatRegion* pSfrLimit, + ISurfFlatRegion* pSfrToUpdate = nullptr) const ; bool CloseOpenEdgesUnderTolerance( ISurfFlatRegion* pSfr, double dToler) ; bool ModifySurfForOpenCloseEdges( ISurfFlatRegion* pSfr, const Vector3d& vtTool, const ICurveComposite* pCrvCompo) const ; bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrRef) const ; @@ -182,6 +183,7 @@ class SurfRoughing : public Machining /* debug functions */ void DrawLoopsSurf( const ISurfFlatRegion* pSfr, bool bWithSurf, Color Col, bool bAlphaCoverage, std::string sName) ; void DrawFeed( const ICurve* pCrv, double dFeed) ; + void DrawNormalShaderSurfTm( const ISurfTriMesh* pStm, std::string sName) ; /* end debug functions */ private :