EgtMachKernel :

- Aggiunta gestione della superficie limite
- aggiunte funzioni per SubSteps
- correzioni varie.
This commit is contained in:
Riccardo Elitropi
2024-06-25 13:30:41 +02:00
parent 63ca83fa01
commit c917f6bb4e
2 changed files with 259 additions and 22 deletions
+254 -20
View File
@@ -75,11 +75,16 @@ using namespace std ;
// 3026 = "Error in SurfRoughing : Detecting open edges failed"
// 3027 = "Error in SurfRoughing : Slicing Raw failed"
// 3028 = "Error in SurfRoughing : Error in CalcPocketing"
// 3029 = "Error in SurfRoughing : Simplify Chunks for SubSteps failed"
// 3051 = "Warning in SurfRoughing : Skipped entity (xx)"
// 3052 = "Warning in SurfRoughing : No machinable path"
// 3053 = "Warning in SurfRoughing : Tool name changed (xx)"
// 3054 = "Warning in SurfRoughing : Tool data changed (xx)"
//----------------------------------------------------------------------------
static string KEY_SURF_POCK = "SurfPock_" ;
static string KEY_SURF_LIMIT = "SurfLimit_" ;
//----------------------------------------------------------------------------
USEROBJ_REGISTER( GetOperationClass( OPER_SURFROUGHING), SurfRoughing) ;
@@ -227,6 +232,7 @@ SurfRoughing::SurfRoughing( void)
m_nStatus = MCH_ST_TO_VERIFY ;
m_nPaths = 0 ;
m_dMaxHelixRad = INFINITO ;
m_dSubStepToler = 2000 * EPS_SMALL ; // proporzionale al raggio utensile o come parametro ???
}
//----------------------------------------------------------------------------
@@ -1241,8 +1247,8 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( vpStm, frPlanes, SILH_TOL))
return false ;
// calcolo le regioni di svuotatura alle varie quote come differenza tra regioni da lavorare e regioni di silhouette
INTVECTOR vPocket ;
// vettore Id salvati nel gruppo Temp
INTINTVECTOR vPocket ;
// definisco la dimensione dello step ( base ) e il numero di passate
double dOkStep = min( m_Params.m_dStep, m_TParams.m_dMaxMat + EPS_SMALL) ;
@@ -1315,6 +1321,7 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
// creo la regione piana di confronto
// su tutti gli step ricavati, calcolo le PolyLine delle Silhouette
int nPocket = 0 ; // numero effettivo di Pocketing calcolate
for ( auto it = vStepInfo.begin() ; it != vStepInfo.end() ; ++ it) {
/* ******************** Regione estesa di lavoro ******************** */
@@ -1366,7 +1373,6 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
}
if ( ! pSfr->IsValid() || pSfr->GetChunkCount() == 0) // se superficie non valida
continue ; // passo allo step successivo ( la silhouette coincide con il grezzo )
// salvo la superficie rimossa
( it->second).pSfrRemoved = pSfr->Clone() ;
@@ -1400,12 +1406,31 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
// se regione risultante non vuota
if ( pSfr->IsValid() && pSfr->GetChunkCount() > 0) {
// se si tratta di un SottoStep, rimuovo tutti i chunk troppo snelli
if ( ( it->second).bSubStep) {
if ( ! RemoveChunksUnderTolerance( pSfr)) {
m_pMchMgr->SetLastError( 3029, "Error in SurfRoughing : Simplify Chunks for SubSteps failed") ;
return false ;
}
// se dopo la semplificazione non rimane nulla, allora passo allo step successivo
if ( ! pSfr->IsValid() || pSfr->GetChunkCount() == 0)
continue ;
}
// determino i lati aperti ( mediante vicinanza dei tratti di curva al volume progressivo non svuotato)
if ( ! ChooseCloseOrOpenEdge( pSfr, pSfrOpenClose)) {
m_pMchMgr->SetLastError( 3026, "Error in SurfRoughing : Detecting open edges failed") ;
return false ;
}
// se si tratta di un SottoStep, chiudo tutti i lati aperti troppo corti
if ( ( it->second).bSubStep) {
if ( ! CloseOpenEdgesUnderTolerance( pSfr, m_TParams.m_dDiam - 200 * EPS_SMALL)) {
m_pMchMgr->SetLastError( 3029, "Error in SurfRoughing : Simplify Chunks for SubSteps failed") ;
return false ;
}
}
// salvo nella temp Prop della FlatRegion se si tratta di uno step base o intermedio
// Step Base -> 0 | Step intermedio -> 1
pSfr->SetTempProp( ( it->second).bSubStep ? 1 : 0, 0) ;
@@ -1414,12 +1439,29 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
pSfr->SetTempParam( ( it->second).dDepth, 0) ;
// la salvo nel gruppo temporaneo
int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfr)) ;
if ( nNewId == GDB_ID_NULL) {
int nNew_SfrPock_Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfr)) ;
if ( nNew_SfrPock_Id == GDB_ID_NULL) {
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
return false ;
}
vPocket.emplace_back( nNewId) ;
m_pGeomDB->SetMaterial( nNew_SfrPock_Id, GREEN) ;
m_pGeomDB->SetName( nNew_SfrPock_Id, KEY_SURF_POCK + ToString( nPocket)) ;
// nel gruppo temporaneo salvo anche la Shilouette ( per superficie Limite)
int nNew_SfrLimit_Id = GDB_ID_NULL ;
if ( ! IsNull( pSfrSil) && pSfrSil->IsValid()) {
nNew_SfrLimit_Id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfrSil)) ;
if ( nNew_SfrLimit_Id == GDB_ID_NULL) {
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
return false ;
}
m_pGeomDB->SetMaterial( nNew_SfrLimit_Id, ORANGE) ;
m_pGeomDB->SetName( nNew_SfrLimit_Id, KEY_SURF_LIMIT + ToString( nPocket)) ;
}
++ nPocket ;
vPocket.emplace_back( make_pair( nNew_SfrPock_Id, nNew_SfrLimit_Id)) ;
}
}
@@ -1625,7 +1667,7 @@ SurfRoughing::GetActiveSurfaces( INTVECTOR& vSurfId) const
//----------------------------------------------------------------------------
bool
SurfRoughing::AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const Vector3d& vtExtr,
SurfRoughing::AddPocket( const INTINTVECTOR& vPocket, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, double dStep, bool bSplitArcs)
{
// recupero distanze di sicurezza
@@ -1637,34 +1679,42 @@ SurfRoughing::AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const
// ciclo sulle regioni
bool bStart = true ;
for ( int nPockId : vPocket) {
for ( auto& vId : vPocket) {
// recupero la superficie da lavorare
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( m_pGeomDB->GetGeoObj( nPockId)) ;
// recupero la superficie da lavorare ( è il primo indice )
const ISurfFlatRegion* pSfrPock = GetSurfFlatRegion( m_pGeomDB->GetGeoObj( vId.first)) ;
// controllo se la regione è relativa ad uno step base o ad uno step intermedio
bool bIsSubStep = ( pSfr->GetTempProp( 0) == 1) ;
bool bIsSubStep = ( pSfrPock->GetTempProp( 0) == 1) ;
// recupero la superficie limite se presente
PtrOwner<ISurfFlatRegion> pSfrLimit( CreateSurfFlatRegion()) ;
if ( vId.second != GDB_ID_NULL) {
const ISurfFlatRegion* pSfrL = GetSurfFlatRegion( m_pGeomDB->GetGeoObj( vId.second)) ;
if ( pSfrL == nullptr)
return false ;
pSfrLimit.Set( pSfrL->Clone()) ;
}
// se il tipo è SPIRAL_OUT e sto gestendo uno step intermedio, lo lavoro come SPIRAL_IN
if ( nSubType == SURFROU_SUB_SPIRALOUT && bIsSubStep)
nSubType = SURFROU_SUB_SPIRALIN ;
ICRVCOMPOPOVECTOR vpCrvs ; // percorso di svuotatura
// se si tratta di uno step base, allora lavoro l'intera superficie
if ( ! CalcPocketing( pSfr, m_TParams.m_dDiam / 2, 0., m_Params.m_dSideStep, m_Params.m_dSideAngle,
nSubType, true, vpCrvs)) {
if ( ! CalcPocketing( pSfrPock, m_TParams.m_dDiam / 2, 0., m_Params.m_dSideStep, m_Params.m_dSideAngle,
nSubType, true, pSfrLimit, vpCrvs)) {
m_pMchMgr->SetLastError( 3028, "Error in SurfRoughing : Error in CalcPocketing") ;
return false ;
}
// recupero la Depth della regione
double dDepth = pSfr->GetTempParam( 0) ;
double dDepth = pSfrPock->GetTempParam( 0) ;
// sistemo gli archi per massimo angolo al centro
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i)
VerifyArcs( vpCrvs[i]) ;
// salvo i loop esterni della superficie corrente come Polylinee ( per LeadIn/LeadOut)
ICURVEPOVECTOR vLoops ; vLoops.resize( pSfr->GetChunkCount()) ;
ICURVEPOVECTOR vLoops ; vLoops.resize( pSfrPock->GetChunkCount()) ;
for ( int c = 0 ; c < int( vLoops.size()) ; ++ c)
vLoops[c].Set( pSfr->GetLoop( c, 0)) ;
vLoops[c].Set( pSfrPock->GetLoop( c, 0)) ;
// ciclo sui percorsi
for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) {
@@ -1738,7 +1788,7 @@ SurfRoughing::AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const
nInd = idx ;
}
}
PtrOwner<ICurveComposite> pCompo( ConvertCurveToComposite( pSfr->GetLoop( nInd, 0))) ;
PtrOwner<ICurveComposite> pCompo( ConvertCurveToComposite( pSfrPock->GetLoop( nInd, 0))) ;
if ( IsNull( pCompo))
return false ;
if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, pCompo,
@@ -2238,7 +2288,191 @@ SurfRoughing::SimplyfySfr( ISurfFlatRegion* pSfr) const
//----------------------------------------------------------------------------
bool
SurfRoughing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrRef)
SurfRoughing::RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr) const
{
/*
quando si lavorano dei SubSteps, può capitare che la superfice da rimuovere sia molto snella;
questo succede quando lo step eseguito in precedenza rimuove gran parte del materiale utile per il
piano di lavoro attuale. Si creano dunque delle regioni formate da più Chunk molto sottili che
creano sia problemi di distinzione dei lati aperti che problemi poi ad essere svuotate ( si pensi
all'estensione dei lati aperti e al loro raccordo con i chiusi, oltre al fatto che i chunk in
questa operazione potrebbero mergiarsi tra loro creando ambiguità.
Data la superficie *pSfr, vengono rimossi tutti i Chunks che si annullano mediante il contro-Offset
definito dalla tolleranza
NB. Il Contro-Offset è possibile farlo solo sul Loop esterno, non c'è bisogno di
fare conti aggiuntivi per le isole interne
*/
// controllo dei parametri
if ( pSfr == nullptr || ! pSfr->IsValid())
return false ;
if ( m_dSubStepToler < EPS_SMALL) // se tolleranza non presente, non faccio nulla
return true ;
// inizializzo la superficie da restituire
PtrOwner<ISurfFlatRegion> pSfrBeauty( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrBeauty))
return false ;
// scorro tutti i chunk della superficie
bool bSameSurf = true ;
for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) {
// recupero il loop esterno
PtrOwner<ICurve> pCrvExtLoop( pSfr->GetLoop( c, 0)) ;
if ( IsNull( pCrvExtLoop) || ! pCrvExtLoop->IsValid())
return false ;
// effettuo l'offset della tolleranza richiesta
OffsetCurve OffsCrv ;
if ( OffsCrv.Make( pCrvExtLoop, - m_dSubStepToler, ICurve::OFF_FILLET)) {
// recupero la curva di Offset
PtrOwner<ICurveComposite> pCrvOffs( ConvertCurveToComposite( OffsCrv.GetLongerCurve())) ;
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid() && pCrvOffs->GetCurveCount() > 0) {
// se valida, allora conservo il chunk
// inserisco la curva esterna
if ( ! pSfrBeauty->AddExtLoop( Release( pCrvExtLoop)))
return false ;
// inserisco le isole del Chunk corrente
for ( int l = 1 ; l < pSfr->GetLoopCount( c) ; ++ l) {
PtrOwner<ICurve> pCrvIsl( pSfr->GetLoop( c, l)) ;
if ( IsNull( pCrvIsl) ||
! pCrvIsl->IsValid() ||
! pSfrBeauty->AddIntLoop( *pCrvIsl))
return false ;
}
continue ; // passo al Chunk successico
}
}
bSameSurf = false ;
}
// se ho fatto modifiche, sostituisco la superficie con quella nuova
if ( ! bSameSurf)
pSfr->CopyFrom( pSfrBeauty) ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::CloseOpenEdgesUnderTolerance( ISurfFlatRegion* pSfr, double dToler)
{
/*
Nei SubSteps capita spesso che ci siano dei lati aperti molto piccoli o delle sequenze di lati
Aperti-Chiusi alternati tutti molto corti ( es. Laurana50K).
Chiudo tutti i lati aperti piccoli
*/
// controllo dei parametri
if ( pSfr == nullptr || ! pSfr->IsValid())
return false ;
if ( dToler < 10 * EPS_SMALL) // se tolleranza non presente, non faccio nulla
return true ;
// inizializzo la superficie da restituire
PtrOwner<ISurfFlatRegion> pSfrRegular( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrRegular))
return false ;
// scorro tutti i chunk della superficie
for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) {
// scorro tutti i loop
for ( int l = 0 ; l < pSfr->GetLoopCount( c) ; ++ l) {
// recupero il loop come curva composita
PtrOwner<ICurveComposite> pCrvLoop( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ;
if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
return false ;
// ------------- ricavo tratti di proprietà uniformi -------------
ICRVCOMPOPOVECTOR vpCrvs ; // vettore tratti aperti e chiusi alternati tra gli indici
int nCurrTempProp ;
int nParStart = 0 ;
for ( int i = 0 ; i < pCrvLoop->GetCurveCount() ; ++ i) { // per ogni curva del loop
int nTempProp ;
pCrvLoop->GetCurveTempProp( i, nTempProp) ;
if ( i == 0) {
nCurrTempProp = nTempProp ;
nParStart = i ;
}
else if ( nCurrTempProp != nTempProp) { // se TempProp0 differente dalla curva precedente
// ricavo il tratto di curva
PtrOwner<ICurveComposite> pCrv( ConvertCurveToComposite( pCrvLoop->CopyParamRange( nParStart, i))) ;
if ( IsNull( pCrv))
return false ;
pCrv->SetTempProp( nCurrTempProp) ;
vpCrvs.emplace_back( Release( pCrv)) ;
nCurrTempProp = nTempProp ;
nParStart = i ;
}
}
// ultima curva ( se esiste)
if ( nParStart < pCrvLoop->GetCurveCount()) {
PtrOwner<ICurveComposite> pCrvLast( ConvertCurveToComposite( pCrvLoop->CopyParamRange( nParStart, pCrvLoop->GetCurveCount()))) ;
if ( IsNull( pCrvLast) || ! pCrvLast->IsValid())
return false ;
pCrvLast->SetTempProp( nCurrTempProp) ;
if ( vpCrvs.empty())
vpCrvs.emplace_back( Release( pCrvLast)) ; // la curva originale aveva tutte propietà uniformi
else {
if ( vpCrvs[0]->GetTempProp( 0) == nCurrTempProp)
vpCrvs[0]->AddCurve( Release( pCrvLast), false) ;
else
vpCrvs.emplace_back( Release( pCrvLast)) ;
}
}
// --------------------------------------------------------------------
//for ( int u = 0 ; u < int( vpCrvs.size()) ; ++ u) {
// if ( vpCrvs[u]->GetTempProp() == 0)
// DrawSimpleCompleteCurve( vpCrvs[u], AQUA) ;
// else if ( vpCrvs[u]->GetTempProp() == 1)
// DrawSimpleCompleteCurve( vpCrvs[u], ORANGE) ;
// else
// DrawSimpleCompleteCurve( vpCrvs[u], GREEN) ;
//}
// scorro tutti i tratti aperti e riconcateno il loop
PtrOwner<ICurveComposite> pCrvNewLoop( CreateCurveComposite()) ;
if ( IsNull( pCrvNewLoop))
return false ;
for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) {
if ( vpCrvs[i]->GetTempProp( 0) == 1 && int( vpCrvs.size()) != 1) { // se tratto aperto e non coincidente a tutta la curva
// semplifico il loop per avere curve più uniformi
SimplifyCurve( vpCrvs[i]) ;
// riporto le proprietà
vpCrvs[i]->SetTempProp( 1) ;
for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j)
vpCrvs[i]->SetCurveTempProp( j, 1, 0) ;
// controllo la lunghezza delle curve
double dLen = EPS_SMALL ;
vpCrvs[i]->GetLength( dLen) ;
if ( dLen < dToler) { // e più corto della tolleranza
vpCrvs[i]->SetTempProp( 0, 0) ;
for ( int j = 0 ; j < vpCrvs[i]->GetCurveCount() ; ++ j)
vpCrvs[i]->SetCurveTempProp( j, 0, 0) ;
}
}
pCrvNewLoop->AddCurve( Release( vpCrvs[i])) ;
}
// inserisco i nuovi loop nella superficie regolare
if ( l == 0) {
if ( ! pSfrRegular->AddExtLoop( Release( pCrvNewLoop)))
return false ;
}
else {
if ( ! pSfrRegular->AddIntLoop( Release( pCrvNewLoop)))
return false ;
}
}
}
// resituisco la superficie
pSfr->CopyFrom( pSfrRegular) ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrRef) const
{
// controllo parametri :
@@ -2254,8 +2488,8 @@ SurfRoughing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfFlatRegio
pSfrRef_Offs->Offset( - 50 * EPS_SMALL, ICurve::OFF_FILLET) ;
// per ogni curva dei Loop della FlatRegion vengono presi 4 punti di controllo equidistanti.
// " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO NON SONO DENTRO AL GREZZO " ( bOnIsClosed = T)
// " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO DISTANO MENO DI 25 * EPS_SMALL DALLE FACCE ( bOnIsClosed = F)
// " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO NON SONO DENTRO AL GREZZO "
// " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO DISTANO MENO DI 25 * EPS_SMALL DALLE FACCE "
const int NUM_POINTS = 4 ;
// scorro tutti i loop
+5 -2
View File
@@ -76,7 +76,7 @@ class SurfRoughing : public Machining
bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ;
bool Chain( int nGrpDestId) ;
bool ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) ;
bool AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const Vector3d& vtExtr,
bool AddPocket( const INTINTVECTOR& vPocket, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, double dStep, bool bSplitArcs) ;
bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;
bool AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;
@@ -96,7 +96,9 @@ class SurfRoughing : public Machining
double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ;
double GetRadiusForStartEndElevation( void) const ;
bool ResetCurveAllTempProp( ICurve* pCurve) const ;
bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrRef) ;
bool RemoveChunksUnderTolerance( ISurfFlatRegion* pSfr) const ;
bool CloseOpenEdgesUnderTolerance( ISurfFlatRegion* pSfr, double dToler) ;
bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfFlatRegion* pSfrRef) const ;
bool SimplifyCurve( ICurveComposite* pCompo) const ;
bool SimplyfySfr( ISurfFlatRegion* pSfr) const ;
bool CalcRetCrv( const ICurveComposite* pCompo, const Point3d& ptRef, bool bOutStart,
@@ -144,4 +146,5 @@ class SurfRoughing : public Machining
int m_nStatus ; // stato di aggiornamento della lavorazione
int m_nPaths ; // numero di percorsi di lavoro generati
double m_dMaxHelixRad ; // raggio massimo attacco ad elica nel caso di cerchi
double m_dSubStepToler ; // tolleranza di rimozione chunk per SubSteps
} ;