EgtMachKernel :

- percorsi di ritorno con Vroni smussati ( algoritmo Douglas-Peucker).
This commit is contained in:
Riccardo Elitropi
2024-01-19 13:35:19 +01:00
parent ea20040495
commit d57198ac19
2 changed files with 159 additions and 2 deletions
+158 -1
View File
@@ -98,7 +98,7 @@ using namespace std ;
// 2438 = "Error in Pocketing : Projecting volume failed"
// 2439 = "Error in Pocketing : Detecting open edges failed"
// 2440 = "Error in Pocketing : Computing second pocket failed"
// 2441 = "Error in Pocketing : Return apth not computable"
// 2441 = "Error in Pocketing : Return path not computable"
// 2451 = "Warning in Pocketing : Skipped entity (xx)"
// 2452 = "Warning in Pocketing : No machinable pocket"
// 2453 = "Warning in Pocketing : Tool name changed (xx)"
@@ -6533,6 +6533,132 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector<ICRVCOMPOPOVECTOR>&
return true ;
}
//----------------------------------------------------------------------------
bool DecimateDP( const double dToll, const PNTVECTOR& vPts, BOOLVECTOR& vbMarks, const int nIndS, const int nIndE)
{
// controllo dei parametri
if ( int( vPts.size()) < 2 || int( vPts.size()) != int( vbMarks.size()) || dToll < EPS_SMALL ||
nIndE >= int( vPts.size()) || nIndS < 0)
return false ;
// se l'indice di partenza supera quello finale, allora ho finito
if ( nIndS >= nIndE - 1)
return true ;
// creo un segmento tra i due punti correnti
PtrOwner<ICurveLine> pSeg( CreateCurveLine()) ;
if ( IsNull( pSeg) || ! pSeg->Set( vPts[nIndS], vPts[nIndE]))
return false ;
// distanza massima e indice del punto a tale distanza dal segmento creato
double dMaxDist = 0. ;
int nIndMaxDist = nIndE ;
// scrorro tutti i vertici tra l'inidice inziale e l'indice finale
for ( int i = nIndS ; i < nIndE ; ++ i) {
// distanza attuale
double dCurrDist = INFINITO ;
DistPointCurve DPC( vPts[i], *pSeg) ;
if ( DPC.GetDist( dCurrDist) && dCurrDist > dMaxDist) { // se maggiore della massima...
// aggiorno
dMaxDist = dCurrDist ;
nIndMaxDist = i ;
}
}
// se la distanza trovata supera la tolleranza, continuo a Splittare
if ( dMaxDist > dToll) {
vbMarks[ nIndMaxDist] = true ;
if ( ! DecimateDP( dToll, vPts, vbMarks, nIndS, nIndMaxDist) ||
! DecimateDP( dToll, vPts, vbMarks, nIndMaxDist, nIndE))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool ApproxPolyLinesDP( PolyLine& PL, const double dToll)
{
// controllo dei parametri
if ( PL.GetPointNbr() < 2 || dToll < EPS_SMALL)
return false ;
// se due punti, la PolyLine è se stessa
if ( PL.GetPointNbr() == 2)
return true ;
// variabili per algoritmo Douglas-Peucker
PNTVECTOR vPts ;
Point3d ptNext ;
PL.GetFirstPoint( ptNext) ;
vPts.push_back( ptNext) ;
while ( PL.GetNextPoint( ptNext))
vPts.push_back( ptNext) ;
BOOLVECTOR vbMarks ; vbMarks.resize( int( vPts.size()), false) ;
// marco il primo e l'ultimo punto
vbMarks.front() = true ;
vbMarks.back() = true ;
// decimazione della PolyLine
if ( ! DecimateDP( dToll, vPts, vbMarks, 0, int( vPts.size()) - 1))
return false ;
// costruzione dei punti
PL.Clear() ;
for ( int i = 0 ; i < int( vbMarks.size()) ; ++ i) {
if ( ! vbMarks[i]) // non considero gli indici non marcati
continue ;
PL.AddUPoint( i, vPts[i]) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool GetApproxCurveDP( const ICurveComposite* pCrvCompo, const double dToll, ICurveComposite* pCrvRes)
{
// controllo dei parametri
if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid() || dToll < EPS_SMALL || pCrvRes == nullptr)
return false ;
pCrvRes->Clear() ;
// creo la PolyLine dalla composita
PolyLine PL ;
int nU = 0 ;
for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) {
Point3d ptS ;
if ( pCrvCompo->GetCurve( u)->GetType() == CRV_LINE) {
if ( ! pCrvCompo->GetCurve( u)->GetStartPoint( ptS) ||
! PL.AddUPoint( nU, ptS))
return false ;
++ nU ;
}
else {
// se arco prendo più punti
PolyLine PL_tmp ;
if ( ! pCrvCompo->GetCurve( u)->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL_tmp))
return false ;
Point3d ptNext ;
PL_tmp.GetFirstPoint( ptNext) ;
PL.AddUPoint( nU, ptNext) ;
++ nU ;
while ( PL_tmp.GetNextPoint( ptNext)) {
PL.AddUPoint( nU, ptNext) ;
++ nU ;
}
}
}
Point3d ptE ;
if ( ! pCrvCompo->GetEndPoint( ptE) ||
! PL.AddUPoint( nU, ptE))
return false ;
// approssimazione Douglas-Peucker
if ( ! ApproxPolyLinesDP( PL, dToll) || PL.GetPointNbr() < 2)
return false ;
// dalla PolyLine recupero la composita
return pCrvRes->FromPolyLine( PL) && pCrvRes->IsValid() ;
}
//----------------------------------------------------------------------------
bool
Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFlatRegion* pSfr,
@@ -6656,9 +6782,40 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl
pCrvStepLink->IsValid() &&
pCrvStepLink->ToGlob( frCurr) ;
// ricavo il parametro massimo sui bisettori da VRONI
double dMinPar = INFINITO ;
for ( int i = 1 ; i < pCrvPath->GetCurveCount() - 1; ++ i) {
double dParS = pCrvPath->GetCurve( i)->GetTempParam( 0) ;
if ( dParS < dMinPar)
dMinPar = dParS ;
}
int r = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfr->Clone()) ;
m_pGeomDB->SetMaterial( r, RED) ;
int g = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrSafe->Clone()) ;
m_pGeomDB->SetMaterial( g, GREEN) ;
PtrOwner<ICurveComposite> pCrvPathH( pCrvPath->Clone()) ;
pCrvPathH->ToGlob( frCurr) ;
int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvPathH->Clone()) ;
m_pGeomDB->SetMaterial( b, BLUE) ;
// approssimo il percorso
PtrOwner<ICurveComposite> pCrvRes( CreateCurveComposite()) ;
if ( ! IsNull( pCrvRes) && GetApproxCurveDP( pCrvPath, dMinPar, pCrvRes))
pCrvPath.Set( Release( pCrvRes)) ;
ModifyCurveToSmoothed( pCrvPath, dMinPar, dMinPar, false) ;
PtrOwner<ICurveComposite> pCrvPathHH( pCrvPath->Clone()) ;
pCrvPathHH->ToGlob( frCurr) ;
b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvPathHH->Clone()) ;
m_pGeomDB->SetMaterial( b, BLACK) ;
return false ;
// aggiungo un tratto lineare per avere il percorso completo
pCrvPath->AddLine( ORIG, false) ;
pCrvPath->AddLine( ptEProj, true) ;
// calcolo la sua lunghezza
double dCurrLen ;
+1 -1
View File
@@ -96,7 +96,7 @@ class Pocketing : public Machining
const Point3d& ptE, ICurveComposite* pCrvPath) ;
bool GetSpecialElevation( const ISurfFlatRegion* pSfr, const ICurveLine* pLine, const bool bInVsOut,
double& dElev) ;
bool GetDangerSfrForSideStep( const ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm_Part, const double dExtraLenInOut,
ISurfFlatRegion* pSfrDanger) ;
bool AdjustTrapezoidSpiralLeadInLeadOutForSideAngle( ICurveComposite* pMCrv, const double dExtraLenInOut,