EgtMachKernel :
- percorsi di ritorno con Vroni smussati ( algoritmo Douglas-Peucker).
This commit is contained in:
+158
-1
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user