EgtMachKernel :

- in PocketingNT esteso il controllo delle facce di una TriMesh
- in PocketingNT forzato ricalcolo se modifica del flag Open.
This commit is contained in:
Riccardo Elitropi
2026-06-24 15:44:54 +02:00
parent ab5f4a7cc4
commit 67cce96f4a
2 changed files with 104 additions and 44 deletions
+103 -44
View File
@@ -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<ISurfTriMesh> pStm( CreateSurfTriMesh()) ;
if ( ! IsNull( pStm) && pStm->AdjustTopology() && pStm->CreateByExtrusion( vPL[0], 4. * m_TParams.m_dDiam * ( - vtFaceN))) {
// recupero la composita associata alla PolyLine
PtrOwner<ICurveComposite> 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<ISurfTriMesh> 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<ICurveComposite> pCompoLoop( CreateCurveComposite()) ;
if ( ! IsNull( pCompoLoop) && pCompoLoop->FromPolyLine( vPLSil[0])) {
PtrOwner<ISurfFlatRegion> 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<ICAvParSilhouettesSurfTm> pCAvParDangSil( CreateCAvParSilhouettesSurfTm()) ;
if ( IsNull( pCAvParDangSil) || ! pCAvParDangSil->SetData( { pStm }, frFace, SIL_TOL))
return false ;
if ( ! pCAvParDangSil->GetSilhouette( 0., vPLSil))
return false ;
}
PtrOwner<ISurfFlatRegion> pSfrSil( nullptr) ;
if ( ! vPLSil.empty()) {
SurfFlatRegionByContours SfrByC ;
for ( const PolyLine& PL : vPLSil) {
PtrOwner<ICurveComposite> 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)) ;
+1
View File
@@ -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
} ;