EgtMachKernel :
- LeadIn/Out con VORONI e Dijkstra ( cammini minimi).
This commit is contained in:
+362
-125
@@ -105,6 +105,7 @@ static string KEY_TOOL = "VTTOOL" ;
|
||||
static int LINK_CURVE_PROP = -3 ;
|
||||
static double FEED_DIVISOR = 1000.0 ;
|
||||
static double TOLL_TRAPEZOID = 50 * EPS_SMALL ;
|
||||
static double SAFE_Z_RET = 5. ;
|
||||
//----------------------------------------------------------------------------
|
||||
USEROBJ_REGISTER( GetOperationClass( OPER_POCKETING), Pocketing) ;
|
||||
|
||||
@@ -1573,7 +1574,6 @@ Pocketing::ChainCurveArray( ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo
|
||||
}
|
||||
|
||||
return true ;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -6010,7 +6010,7 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector<ICRVCOMPOPOVECTOR>&
|
||||
Point3d ptDest ; vMCrv[i]->GetStartPoint( ptDest) ;
|
||||
// calcolo il percorso di ritorno del percorso attuale
|
||||
if ( IsNull( pRCrv) ||
|
||||
! CalcLinkOnStep( ptCurr, ptDest, dSafeZ, vSfr[j-2], pRCrv)) {
|
||||
! CalcLinkOnStep( ptCurr, ptDest, vSfr[j-2], pRCrv)) {
|
||||
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
|
||||
return false ;
|
||||
}
|
||||
@@ -6024,12 +6024,7 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector<ICRVCOMPOPOVECTOR>&
|
||||
// ricavo la posizione attuale
|
||||
Point3d ptAbove ; GetCurrPos( ptAbove) ;
|
||||
double dStElev = Dist( ptAbove, ptStart) ;
|
||||
// approccio al punto iniziale
|
||||
//if ( ! AddApproach( ptAbove, vtTool, dSafeZ, dSafeAggrBottZ, dStElev, dAppr, vbOut[i])) {
|
||||
// m_pMchMgr->SetLastError( 2414, "Error in Pocketing : Approach not computable") ;
|
||||
// return false ;
|
||||
//}
|
||||
// aggiungo attacco
|
||||
// aggiungo attacco ( solo collegamento )
|
||||
SetFeed( GetStartFeed()) ;
|
||||
if ( ! AddLeadIn( ptAbove, ptStart, vtStart, vtExtr, pSrfLeanInOut, vRCrv[i], !m_Params.m_bInvert, bSplitArcs, vbOut[i])) {
|
||||
m_pMchMgr->SetLastError( 2415, "Error in Pocketing : LeadIn not computable") ;
|
||||
@@ -6092,7 +6087,7 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector<ICRVCOMPOPOVECTOR>&
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double& dSafeZ, const ISurfFlatRegion* pSfr,
|
||||
Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFlatRegion* pSfr,
|
||||
ICurveComposite* pCrvStepLink)
|
||||
{
|
||||
// ptS -> punto finale del percorso attuale di pocketing
|
||||
@@ -6144,10 +6139,8 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double&
|
||||
if ( int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_IN)
|
||||
// creo il tratto lineare leggermente rialzato
|
||||
return pCrvStepLink->AddPoint( ORIG) &&
|
||||
pCrvStepLink->AddLine( ORIG + dSafeZ * Z_AX) &&
|
||||
pCrvStepLink->SetCurveTempProp( 0, FEED_DIVISOR * GetEndFeed(), 0) &&
|
||||
pCrvStepLink->AddLine( ptEProj + dSafeZ * Z_AX) &&
|
||||
pCrvStepLink->SetCurveTempProp( 1, FEED_DIVISOR * GetEndFeed(), 0) &&
|
||||
pCrvStepLink->AddLine( ORIG + SAFE_Z_RET * Z_AX) &&
|
||||
pCrvStepLink->AddLine( ptEProj + SAFE_Z_RET * Z_AX) &&
|
||||
pCrvStepLink->IsValid() &&
|
||||
pCrvStepLink->ToGlob( frCurr) ;
|
||||
|
||||
@@ -6172,10 +6165,8 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double&
|
||||
// se l'elevazione massima è nulla, allora sono sempre fuori dal grezzo ( quindi passo per i lati aperti)
|
||||
if ( dMAxElev < EPS_SMALL)
|
||||
return pCrvStepLink->AddPoint( ORIG) &&
|
||||
pCrvStepLink->AddLine( ORIG + dSafeZ * Z_AX) &&
|
||||
pCrvStepLink->SetCurveTempProp( 0, FEED_DIVISOR * GetEndFeed(), 0) &&
|
||||
pCrvStepLink->AddLine( ptEProj + dSafeZ * Z_AX) &&
|
||||
pCrvStepLink->SetCurveTempProp( 1, FEED_DIVISOR * GetEndFeed(), 0) &&
|
||||
pCrvStepLink->AddLine( ORIG + SAFE_Z_RET * Z_AX) &&
|
||||
pCrvStepLink->AddLine( ptEProj + SAFE_Z_RET * Z_AX) &&
|
||||
pCrvStepLink->IsValid() &&
|
||||
pCrvStepLink->ToGlob( frCurr) ;
|
||||
|
||||
@@ -6187,15 +6178,92 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double&
|
||||
vCrvBisectors.empty())
|
||||
return false ;
|
||||
|
||||
// porto i bisettori nel riferimento corrente e cerco le due curve più vicine a ORIG ( pts) e ptEProj
|
||||
// porto i bisettori nel riferimento
|
||||
for ( int i = 0 ; i < ( int)vCrvBisectors.size() ; ++ i)
|
||||
vCrvBisectors[i]->ToLoc( frCurr) ;
|
||||
// trasformo in composite concatenando le curve ( bloccandomi alle biforcazioni)
|
||||
ICRVCOMPOPOVECTOR vCompoBisChain ;
|
||||
if ( ! ChainBisectors( vCrvBisectors, vCompoBisChain))
|
||||
return false ;
|
||||
// pulisco
|
||||
vCrvBisectors.clear() ;
|
||||
// calcolo il percorso ottimale
|
||||
PtrOwner<ICurveComposite> pCrvPath( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvPath) ||
|
||||
! ChooseBestBisectorPath( vCompoBisChain, ORIG, ptEProj, pCrvPath))
|
||||
return false ;
|
||||
// controllo che la curva si effettivamente distante dal percorso, altrimenti scarico
|
||||
bool bSkip = false ;
|
||||
for ( int j = 1 ; j < int( pCrvPath->GetCurveCount()) -1 && ! bSkip ; ++ j)
|
||||
bSkip = pCrvPath->GetCurve( j)->GetTempParam( 0) < m_TParams.m_dDiam * 0.5 ||
|
||||
pCrvPath->GetCurve( j)->GetTempParam( 1) < m_TParams.m_dDiam * 0.5 ;
|
||||
if ( bSkip)
|
||||
return pCrvStepLink->AddPoint( ORIG) &&
|
||||
pCrvStepLink->AddLine( ORIG + ( SAFE_Z_RET + dMAxElev) * Z_AX) &&
|
||||
pCrvStepLink->AddLine( ptEProj + ( SAFE_Z_RET + dMAxElev) * Z_AX) &&
|
||||
( dMAxElev - SAFE_Z_RET > 0 ? pCrvStepLink->AddLine( ptEProj + SAFE_Z_RET * Z_AX) : true) &&
|
||||
pCrvStepLink->IsValid() &&
|
||||
pCrvStepLink->ToGlob( frCurr) ;
|
||||
|
||||
// aggiungo un tratto lineare per avere il percorso completo
|
||||
pCrvPath->AddLine( ORIG, false) ;
|
||||
pCrvPath->AddLine( ptEProj, true) ;
|
||||
|
||||
// calcolo la sua lunghezza
|
||||
double dCurrLen ;
|
||||
if ( ! pCrvPath->GetLength( dCurrLen))
|
||||
return false ;
|
||||
|
||||
// merge delle curve e smusso il miglior percorso trovato
|
||||
pCrvPath->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL) ;
|
||||
// approssimo con PolyArc
|
||||
PolyArc PA ;
|
||||
if ( ! pCrvPath->ApproxWithArcsEx( 500 * EPS_SMALL, ANG_TOL_STD_DEG, LIN_FEA_STD, PA))
|
||||
return false ;
|
||||
pCrvPath->Clear() ;
|
||||
pCrvPath->FromPolyArc( PA) ;
|
||||
ModifyCurveToSmoothed( pCrvPath, m_TParams.m_dDiam / 16, m_TParams.m_dDiam / 16,
|
||||
false) ;
|
||||
|
||||
// valuto se invece è più conveniente scaricare ( quindi alzandomi di dMaxElev)
|
||||
// la lunghezza del tratto in salita e in discesa è dMaxElev
|
||||
// la lunghezza del tratto orizzontale è data dalla distanza tra ORIG e ptEProj
|
||||
if ( dCurrLen < 2 * dMAxElev + Dist( ORIG, ptEProj))
|
||||
// privilegio il percorso
|
||||
return pCrvStepLink->AddPoint( ORIG) &&
|
||||
pCrvStepLink->AddLine( ORIG + SAFE_Z_RET * Z_AX) &&
|
||||
pCrvPath->Translate( SAFE_Z_RET * Z_AX) &&
|
||||
pCrvStepLink->AddCurve( Release( pCrvPath)) &&
|
||||
pCrvStepLink->IsValid() &&
|
||||
pCrvStepLink->ToGlob( frCurr) ;
|
||||
|
||||
// privilegio lo scarico
|
||||
return pCrvStepLink->AddPoint( ORIG) &&
|
||||
pCrvStepLink->AddLine( ORIG + ( SAFE_Z_RET + dMAxElev) * Z_AX) &&
|
||||
pCrvStepLink->AddLine( ptEProj + ( SAFE_Z_RET + dMAxElev) * Z_AX) &&
|
||||
( dMAxElev - SAFE_Z_RET > 0 ? pCrvStepLink->AddLine( ptEProj + SAFE_Z_RET * Z_AX) : true) &&
|
||||
pCrvStepLink->IsValid() &&
|
||||
pCrvStepLink->ToGlob( frCurr) ;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Pocketing::ChooseBestBisectorPath( ICRVCOMPOPOVECTOR& vCrvCompo, const Point3d& ptS,
|
||||
const Point3d& ptE, ICurveComposite* pCrvPath)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( vCrvCompo.empty() || ! ptS.IsValid() || ! ptE.IsValid())
|
||||
return false ;
|
||||
pCrvPath->Clear() ;
|
||||
|
||||
// cerco gli indici delle curve più vicine a ptS e ptE
|
||||
double dMinDistORIG = INFINITO, dMinDistEnd = INFINITO ;
|
||||
int nIndS, nIndE ;
|
||||
Point3d ptCheck ; // punto sulla curva finale più vicina a ptEProj
|
||||
for ( int i = 0 ; i < ( int)vCrvBisectors.size() ; ++ i) {
|
||||
vCrvBisectors[i]->ToLoc( frCurr) ;
|
||||
for ( int i = 0 ; i < ( int)vCrvCompo.size() ; ++ i) {
|
||||
double dCurrDistORIG, dCurrDistEND ;
|
||||
if ( ! DistPointCurve( ORIG, *vCrvBisectors[i]).GetDist( dCurrDistORIG) ||
|
||||
! DistPointCurve( ptEProj, *vCrvBisectors[i]).GetDist( dCurrDistEND))
|
||||
if ( ! DistPointCurve( ptS, *vCrvCompo[i]).GetDist( dCurrDistORIG) ||
|
||||
! DistPointCurve( ptE, *vCrvCompo[i]).GetDist( dCurrDistEND))
|
||||
return false ;
|
||||
if ( dCurrDistORIG < dMinDistORIG) {
|
||||
dMinDistORIG = dCurrDistORIG ;
|
||||
@@ -6204,114 +6272,283 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double&
|
||||
if ( dCurrDistEND < dMinDistEnd) {
|
||||
dMinDistEnd = dCurrDistEND ;
|
||||
nIndE = i ;
|
||||
if ( ! vCrvBisectors[i]->GetMidPoint( ptCheck))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// porto la curva più vicina a ORIG ( ptS) in prima posizione
|
||||
swap( vCrvBisectors[0], vCrvBisectors[nIndS]) ;
|
||||
|
||||
// concateno le curve per cercare dei percorsi ammissibili
|
||||
ICRVCOMPOPOVECTOR vCompoBisChain ;
|
||||
if ( ! ChainCurveArray( vCrvBisectors, vCompoBisChain))
|
||||
// cerco il punto più vicino al bisettore
|
||||
double dUS, dUE ;
|
||||
Point3d ptBisS, ptBisE ;
|
||||
int nFlag ;
|
||||
if ( ! DistPointCurve( ptS, *vCrvCompo[nIndS]).GetMinDistPoint( EPS_SMALL, ptBisS, nFlag) ||
|
||||
! DistPointCurve( ptE, *vCrvCompo[nIndE]).GetMinDistPoint( EPS_SMALL, ptBisE, nFlag) ||
|
||||
! vCrvCompo[nIndS]->GetParamAtPoint( ptBisS, dUS, 10 * EPS_SMALL) ||
|
||||
! vCrvCompo[nIndE]->GetParamAtPoint( ptBisE, dUE, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
|
||||
// per ogni percorso trovato
|
||||
int nIndBestPath = -1 ;
|
||||
double dLenBestPath = INFINITO ;
|
||||
for ( int i = 0 ; i < int( vCompoBisChain.size()) ; ++ i) {
|
||||
// non considero il percorso se esso non contiene ptCheck
|
||||
if ( ! vCompoBisChain[i]->IsPointOn( ptCheck, 10 * EPS_SMALL))
|
||||
continue ;
|
||||
// Spezzo nei punti più vicini a
|
||||
// ORIG ( ptS) e ptEProj e raccordo linearmente l'inizio e la fine a tali punti ( se necessario)
|
||||
// NB. Non è esclusa la possibilità che ORIG ( ptS) e ptEProj siano già sul bisettore
|
||||
double dUS = 0, dUE = vCompoBisChain[i]->GetCurveCount() ;
|
||||
// cerco il punto più vicino al bosettore
|
||||
Point3d ptBisS, ptBisE ;
|
||||
int nFlag ;
|
||||
if ( ! DistPointCurve( ORIG, *vCompoBisChain[i]).GetMinDistPoint( EPS_SMALL, ptBisS, nFlag) ||
|
||||
! DistPointCurve( ptEProj, *vCompoBisChain[i]).GetMinDistPoint( EPS_SMALL, ptBisE, nFlag))
|
||||
return false ;
|
||||
|
||||
if ( ! vCompoBisChain[i]->GetParamAtPoint( ptBisS, dUS, 10 * EPS_SMALL) ||
|
||||
! vCompoBisChain[i]->GetParamAtPoint( ptBisE, dUE, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( dUS > dUE) // potrebbe succedere...
|
||||
swap( dUS, dUE) ;
|
||||
if ( ! vCompoBisChain[i]->TrimStartEndAtParam( dUS, dUE))
|
||||
return false ;
|
||||
|
||||
// controllo che tutte curve non estremanti del percorso siano sufficientemente distanti
|
||||
// dai bordi della pSfrSafe
|
||||
bool bSkip = false ;
|
||||
for ( int j = 1 ; j < int( vCompoBisChain[i]->GetCurveCount()) -1 && ! bSkip ; ++ j)
|
||||
bSkip = vCompoBisChain[i]->GetCurve( j)->GetTempParam( 0) < m_TParams.m_dDiam * 0.5 ||
|
||||
vCompoBisChain[i]->GetCurve( j)->GetTempParam( 1) < m_TParams.m_dDiam * 0.5 ;
|
||||
|
||||
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCompoBisChain[i]->Clone()) ;
|
||||
vCompoBisChain[i]->AddLine( ORIG, false) ;
|
||||
vCompoBisChain[i]->AddLine( ptEProj, true) ;
|
||||
m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCompoBisChain[i]->Clone()) ;
|
||||
|
||||
// calcolo l'elevazione sopra all'ultimo tratto lineare
|
||||
Point3d ptCS ; vCompoBisChain[i]->GetLastCurve()->GetStartPoint( ptCS) ;
|
||||
Point3d ptCE ; vCompoBisChain[i]->GetLastCurve()->GetEndPoint( ptCE) ;
|
||||
double dElevCheck = 0. ;
|
||||
if ( ! GetElevation( m_nPhase, ptCS, ptCE, pSfr->GetNormVersor(), m_TParams.m_dDiam * 0.5, m_TParams.m_dLen,
|
||||
pSfr->GetNormVersor(), dElevCheck))
|
||||
return false ;
|
||||
// se non nulla, allora non considero valido il percorso
|
||||
if ( dElevCheck > EPS_SMALL)
|
||||
continue ;
|
||||
|
||||
// calcolo la sua lunghezza
|
||||
double dCurrLen ;
|
||||
if ( ! vCompoBisChain[i]->GetLength( dCurrLen))
|
||||
return false ;
|
||||
// aggiorno i parametri se di lunghezza inferiore
|
||||
if ( dCurrLen < dLenBestPath) {
|
||||
dLenBestPath = dCurrLen ;
|
||||
nIndBestPath = i ;
|
||||
// splitto le curve più vicine sui rispettivi punti ( se non coincidenti a degli estremi)
|
||||
if ( nIndS != nIndE) {
|
||||
// se le curve sono distinte
|
||||
if ( dUS > 2 * EPS_SMALL && dUS < vCrvCompo[nIndS]->GetCurveCount() - 2 * EPS_SMALL) {
|
||||
PtrOwner<ICurveComposite> pCrvBef( ConvertCurveToComposite( vCrvCompo[nIndS]->CopyParamRange( 0, dUS))) ;
|
||||
PtrOwner<ICurveComposite> pCrvAft( ConvertCurveToComposite( vCrvCompo[nIndS]->CopyParamRange( dUS,
|
||||
vCrvCompo[nIndS]->GetCurveCount()))) ;
|
||||
if ( IsNull( pCrvBef) || ! pCrvBef->IsValid() || IsNull( pCrvAft) || ! pCrvAft->IsValid())
|
||||
return false ;
|
||||
vCrvCompo[nIndS].Set( Release( pCrvBef)) ;
|
||||
vCrvCompo.emplace_back( Release( pCrvAft)) ;
|
||||
}
|
||||
if ( dUE > 2 * EPS_SMALL && dUE < vCrvCompo[nIndE]->GetCurveCount() - 2 * EPS_SMALL) {
|
||||
PtrOwner<ICurveComposite> pCrvBef( ConvertCurveToComposite( vCrvCompo[nIndE]->CopyParamRange( 0, dUE))) ;
|
||||
PtrOwner<ICurveComposite> pCrvAft( ConvertCurveToComposite( vCrvCompo[nIndE]->CopyParamRange( dUE,
|
||||
vCrvCompo[nIndE]->GetCurveCount()))) ;
|
||||
if ( IsNull( pCrvBef) || ! pCrvBef->IsValid() || IsNull( pCrvAft) || ! pCrvAft->IsValid())
|
||||
return false ;
|
||||
vCrvCompo[nIndE].Set( Release( pCrvBef)) ;
|
||||
vCrvCompo.emplace_back( Release( pCrvAft)) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// se la curva è la stessa
|
||||
if ( abs( dUS - dUE) < 5 * EPS_SMALL) {
|
||||
// se coincidenti
|
||||
PtrOwner<ICurveComposite> pCrvBef( ConvertCurveToComposite( vCrvCompo[nIndS]->CopyParamRange( 0, 0.5 * ( dUS + dUE)))) ;
|
||||
PtrOwner<ICurveComposite> pCrvAft( ConvertCurveToComposite( vCrvCompo[nIndS]->CopyParamRange( 0.5 * ( dUS + dUE),
|
||||
vCrvCompo[nIndS]->GetCurveCount()))) ;
|
||||
if ( IsNull( pCrvBef) || ! pCrvBef->IsValid() || IsNull( pCrvAft) || ! pCrvAft->IsValid())
|
||||
return false ;
|
||||
vCrvCompo[nIndS].Set( Release( pCrvBef)) ;
|
||||
vCrvCompo.emplace_back( Release( pCrvAft)) ;
|
||||
}
|
||||
else {
|
||||
// se distinti...
|
||||
if ( dUS > dUE)
|
||||
swap( dUS, dUE) ;
|
||||
PtrOwner<ICurveComposite> pCrvBef( ConvertCurveToComposite( vCrvCompo[nIndS]->CopyParamRange( 0, dUS))) ;
|
||||
PtrOwner<ICurveComposite> pCrvAft( ConvertCurveToComposite( vCrvCompo[nIndS]->CopyParamRange( dUE,
|
||||
vCrvCompo[nIndS]->GetCurveCount()))) ;
|
||||
PtrOwner<ICurveComposite> pCrvBet( ConvertCurveToComposite( vCrvCompo[nIndS]->CopyParamRange( dUS, dUE))) ;
|
||||
if ( IsNull( pCrvBef) || ! pCrvBef->IsValid() || IsNull( pCrvAft) || ! pCrvAft->IsValid() ||
|
||||
IsNull( pCrvBet) || ! pCrvBef->IsValid())
|
||||
return false ;
|
||||
vCrvCompo[nIndS].Set( Release( pCrvBef)) ;
|
||||
vCrvCompo.emplace_back( Release( pCrvBet)) ;
|
||||
vCrvCompo.emplace_back( Release( pCrvAft)) ;
|
||||
}
|
||||
}
|
||||
// se non ho trovato un percorso valido , privilegio lo scarico ed esco
|
||||
if ( nIndBestPath < 0)
|
||||
return pCrvStepLink->AddPoint( ORIG) &&
|
||||
pCrvStepLink->AddLine( ORIG + ( dSafeZ + dMAxElev) * Z_AX) &&
|
||||
pCrvStepLink->AddLine( ptEProj + ( dSafeZ + dMAxElev) * Z_AX) &&
|
||||
pCrvStepLink->IsValid() &&
|
||||
pCrvStepLink->ToGlob( frCurr) ;
|
||||
|
||||
// smusso il miglior percorso trovato
|
||||
ModifyCurveToSmoothed( vCompoBisChain[nIndBestPath], m_TParams.m_dDiam / 16, m_TParams.m_dDiam / 16,
|
||||
false) ;
|
||||
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
|
||||
int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, vCrvCompo[i]->Clone()) ;
|
||||
m_pGeomDB->SetMaterial( b, BLUE) ;
|
||||
}
|
||||
|
||||
// assegno la Feed al percorso
|
||||
for ( int i = 0 ; i < vCompoBisChain[nIndBestPath]->GetCurveCount() ; ++ i)
|
||||
vCompoBisChain[nIndBestPath]->SetCurveTempProp( i, FEED_DIVISOR * GetEndFeed(), 0) ;
|
||||
// definizioni per l'albero su cui calcolare i percorsi minimi
|
||||
struct Link {
|
||||
int nIndNodA ;
|
||||
int nIndNodB ;
|
||||
double dWeight ;
|
||||
int nCrvIndex ;
|
||||
} ;
|
||||
vector<Point3d> Nodes ;
|
||||
vector<Link> Links ;
|
||||
|
||||
// valuto se invece è più conveniente scaricare ( quindi alzandomi di dMaxElev)
|
||||
// la lunghezza del tratto in salita e in discesa è dMaxElev
|
||||
// la lunghezza del tratto orizzontale è data dalla distanza tra ORIG e ptEProj
|
||||
if ( dLenBestPath > 2 * dMAxElev + Dist( ORIG, ptEProj))
|
||||
// privilegio il percorso
|
||||
return pCrvStepLink->AddPoint( ORIG) &&
|
||||
pCrvStepLink->AddLine( ORIG + dSafeZ * Z_AX) &&
|
||||
pCrvStepLink->SetCurveTempProp( 0, FEED_DIVISOR * GetEndFeed(), 0) &&
|
||||
vCompoBisChain[nIndBestPath]->Translate( dSafeZ * Z_AX) &&
|
||||
pCrvStepLink->AddCurve( Release( vCompoBisChain[nIndBestPath])) &&
|
||||
pCrvStepLink->IsValid() &&
|
||||
pCrvStepLink->ToGlob( frCurr) ;
|
||||
// inserisco il nodo sorgente nel vettore dei nodi in posizione 0
|
||||
Nodes.push_back( ptBisS) ;
|
||||
|
||||
// privilegio lo scarico
|
||||
return pCrvStepLink->AddPoint( ORIG) &&
|
||||
pCrvStepLink->AddLine( ORIG + ( dSafeZ + dMAxElev) * Z_AX) &&
|
||||
pCrvStepLink->SetCurveTempProp( 0, FEED_DIVISOR * GetEndFeed(), 0) &&
|
||||
pCrvStepLink->AddLine( ptEProj + ( dSafeZ + dMAxElev) * Z_AX) &&
|
||||
pCrvStepLink->SetCurveTempProp( 1, FEED_DIVISOR * GetEndFeed(), 0) &&
|
||||
pCrvStepLink->IsValid() &&
|
||||
pCrvStepLink->ToGlob( frCurr) ;
|
||||
// il nodo destinazione sarà all'indice nDestInd
|
||||
int nDestInd = - 1 ;
|
||||
|
||||
// creo il vettore di nodi e di Archi
|
||||
for ( int i = 0 ; i < int( vCrvCompo.size()) ; ++ i) {
|
||||
Point3d ptA, ptB ;
|
||||
double dLen = 0.;
|
||||
if ( ! vCrvCompo[i]->GetStartPoint( ptA) || ! vCrvCompo[i]->GetEndPoint( ptB) ||
|
||||
! vCrvCompo[i]->GetLength( dLen))
|
||||
return false ;
|
||||
// inserisco i due possibili nodi se non già presenti rispettivamente
|
||||
bool bInsertA = true ;
|
||||
bool bInsertB = true ;
|
||||
for ( int j = 0 ; j < int( Nodes.size()) ; ++ j) {
|
||||
if ( AreSamePointEpsilon( ptA, Nodes[j], 5 * EPS_SMALL))
|
||||
bInsertA = false ;
|
||||
if ( AreSamePointEpsilon( ptB, Nodes[j], 5 * EPS_SMALL))
|
||||
bInsertB = false ;
|
||||
if ( nDestInd == -1)
|
||||
if ( AreSamePointEpsilon( ptBisE, Nodes[j], 5 * EPS_SMALL))
|
||||
nDestInd = j ;
|
||||
}
|
||||
if ( bInsertA)
|
||||
Nodes.push_back( ptA) ;
|
||||
if ( bInsertB)
|
||||
Nodes.push_back( ptB) ;
|
||||
|
||||
// inserisco l'Arco
|
||||
int nIndA = -1 ; int nIndB = -1 ;
|
||||
for ( int j = 0 ; j < int( Nodes.size()) ; ++ j) {
|
||||
if ( AreSamePointEpsilon( ptA, Nodes[j], 5 * EPS_SMALL))
|
||||
nIndA = j ;
|
||||
if ( AreSamePointEpsilon( ptB, Nodes[j], 5 * EPS_SMALL))
|
||||
nIndB = j ;
|
||||
}
|
||||
if ( nIndA == -1 || nIndB == -1) // controllo...
|
||||
return false ;
|
||||
Link CurrLink ;
|
||||
CurrLink.dWeight = dLen ;
|
||||
CurrLink.nIndNodA = nIndA ;
|
||||
CurrLink.nIndNodB = nIndB ;
|
||||
CurrLink.nCrvIndex = i ;
|
||||
Links.push_back( CurrLink) ;
|
||||
}
|
||||
if ( nDestInd == -1)
|
||||
return false ;
|
||||
|
||||
// calcolo il percorso minimo (Dijkstra)
|
||||
vector<double> vdDist ; vdDist.resize( int( Nodes.size())) ;
|
||||
INTVECTOR vnIndPrec ; vnIndPrec.resize( int( Nodes.size())) ;
|
||||
set<int> SetNode_to_check ;
|
||||
|
||||
for ( int i = 0 ; i < int( Nodes.size()) ; ++ i) {
|
||||
vdDist[i] = INFINITO ;
|
||||
vnIndPrec[i] = -1 ;
|
||||
SetNode_to_check.insert( i) ;
|
||||
}
|
||||
|
||||
vdDist[0] = 0. ;
|
||||
|
||||
while ( ! SetNode_to_check.empty()) {
|
||||
// cerco il vertice in SetNode_to_check con distanza minima associata
|
||||
int nMinInd = -1 ;
|
||||
double dDistRef = INFINITO - 1 ;
|
||||
for ( int j = 0 ; j < int( Nodes.size()) ; ++ j) {
|
||||
set<int>::iterator iter = SetNode_to_check.find( j) ;
|
||||
if ( iter == SetNode_to_check.end())
|
||||
continue ;
|
||||
if ( vdDist[j] < dDistRef) {
|
||||
dDistRef = vdDist[j] ;
|
||||
nMinInd = j ;
|
||||
}
|
||||
}
|
||||
if ( nMinInd == -1 || nMinInd == nDestInd)
|
||||
break ;
|
||||
|
||||
SetNode_to_check.erase( nMinInd) ;
|
||||
|
||||
// cerco i nodi collegati al nodo in esame
|
||||
vector<INTINT> NeightBourInfo ;
|
||||
for ( int j = 0 ; j < int( Links.size()) ; ++ j) {
|
||||
if ( Links[j].nIndNodA == nMinInd || Links[j].nIndNodB == nMinInd) {
|
||||
INTINT Info ;
|
||||
Info.first = j ; // indice del link
|
||||
Info.second = Links[j].nIndNodA == nMinInd ? Links[j].nIndNodB : Links[j].nIndNodA ; // indice dell'altro nodo
|
||||
NeightBourInfo.push_back( Info) ;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int j = 0 ; j < int( NeightBourInfo.size()) ; ++ j) {
|
||||
double dCurrWeight = vdDist[nMinInd] + Links[NeightBourInfo[j].first].dWeight ;
|
||||
if ( dCurrWeight < vdDist[NeightBourInfo[j].second]) {
|
||||
vdDist[NeightBourInfo[j].second] = dCurrWeight ;
|
||||
vnIndPrec[NeightBourInfo[j].second] = nMinInd ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// inserisco il punto iniziale alla curva da restituire
|
||||
pCrvPath->AddPoint( ptBisE) ;
|
||||
|
||||
// percorro a ritroso i Nodi indivisuati
|
||||
int nIndCurrNode = nDestInd ;
|
||||
int nIndPrecNode = -1 ;
|
||||
while ( vnIndPrec[nIndCurrNode] != -1) {
|
||||
nIndPrecNode = vnIndPrec[nIndCurrNode] ;
|
||||
// cerco l'arco con estremanti tali nodi
|
||||
for ( int i = 0 ; i < int( Links.size()) ; ++ i) {
|
||||
if (( Links[i].nIndNodA == nIndCurrNode && Links[i].nIndNodB == nIndPrecNode) ||
|
||||
( Links[i].nIndNodA == nIndPrecNode && Links[i].nIndNodB == nIndCurrNode)) {
|
||||
if ( ! pCrvPath->AddCurve( vCrvCompo[i]->Clone())) {
|
||||
vCrvCompo[i]->Invert() ;
|
||||
if ( ! pCrvPath->AddCurve( vCrvCompo[i]->Clone()))
|
||||
return false ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
}
|
||||
nIndCurrNode = nIndPrecNode ;
|
||||
}
|
||||
|
||||
// controllo se il percorso trovato è ammissibile e che il punto iniziale e finale che coincidano
|
||||
// a quelli ricavati
|
||||
Point3d ptSCheck, ptECheck ;
|
||||
return pCrvPath->IsValid() &&
|
||||
pCrvPath->Invert() &&
|
||||
pCrvPath->GetStartPoint( ptSCheck) &&
|
||||
AreSamePointEpsilon( ptBisS, ptSCheck, 5 * EPS_SMALL) &&
|
||||
pCrvPath->GetEndPoint( ptECheck) &&
|
||||
AreSamePointEpsilon( ptBisE, ptECheck, 5 * EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Pocketing::ChainBisectors( ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo)
|
||||
{
|
||||
// controllo dei parametri
|
||||
if ( int( vpCrvs.size()) == 0)
|
||||
return false ;
|
||||
vCrvCompo.clear() ;
|
||||
|
||||
// preparo i dati per il concatenamento
|
||||
bool bFirst = true ;
|
||||
Point3d ptNear = ORIG ;
|
||||
double dToler = 10 * EPS_SMALL ;
|
||||
ChainCurves chainC ;
|
||||
chainC.Init( true, dToler, int( vpCrvs.size())) ;
|
||||
for ( size_t i = 0 ; i < vpCrvs.size() ; ++ i) {
|
||||
// recupero la curva e il suo riferimento
|
||||
ICurve* pCrv = vpCrvs[i] ;
|
||||
if ( pCrv == nullptr)
|
||||
continue ;
|
||||
// recupero i dati della curva necessari al concatenamento e li assegno
|
||||
Point3d ptStart, ptEnd ;
|
||||
Vector3d vtStart, vtEnd ;
|
||||
if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetStartDir( vtStart) ||
|
||||
! pCrv->GetEndPoint( ptEnd) || ! pCrv->GetEndDir( vtEnd))
|
||||
return false ;
|
||||
if ( ! chainC.AddCurve( int( i + 1), ptStart, vtStart, ptEnd, vtEnd))
|
||||
return false ;
|
||||
// se prima curva, assegno inizio della ricerca
|
||||
if ( bFirst) {
|
||||
ptNear = ptStart + 10 * EPS_SMALL * vtStart ;
|
||||
bFirst = false ;
|
||||
}
|
||||
}
|
||||
// recupero i percorsi concatenati
|
||||
int nCount = 0 ;
|
||||
INTVECTOR vnId2 ;
|
||||
while ( chainC.GetChainFromNear( ptNear, true, vnId2)) {
|
||||
// creo una curva composita
|
||||
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
||||
if ( IsNull( pCrvCompo))
|
||||
return false ;
|
||||
// recupero le curve semplici e le inserisco nella curva composita
|
||||
for ( size_t i = 0 ; i < vnId2.size() ; ++ i) {
|
||||
int nId = abs( vnId2[i]) - 1 ;
|
||||
bool bInvert = ( vnId2[i] < 0) ;
|
||||
// recupero la curva
|
||||
ICurve* pCrv = vpCrvs[nId] ;
|
||||
// se necessario, la inverto
|
||||
if ( bInvert)
|
||||
pCrv->Invert() ;
|
||||
// la aggiungo alla curva composta
|
||||
if ( ! pCrvCompo->AddCurve( ::Release( vpCrvs[nId]), true, dToler))
|
||||
return false ;
|
||||
}
|
||||
// se non sono state inserite curve, vado oltre
|
||||
if ( pCrvCompo->GetCurveCount() == 0)
|
||||
continue ;
|
||||
// aggiungo la curva al vettore di curve composite concatenate
|
||||
vCrvCompo.emplace_back( Release( pCrvCompo)) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
|
||||
}
|
||||
|
||||
@@ -6953,7 +7190,7 @@ Pocketing::CalcSpiral( const ISurfFlatRegion* pSrfPock, int& nReg, Point3d& ptSt
|
||||
for ( int j = nCrvsCount0 ; j < pMCrv->GetCurveCount() ; ++ j)
|
||||
pMCrv->SetCurveTempProp( j, LINK_CURVE_PROP) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
pMCrv->AddCurve( vOffs[i]->Clone()) ;
|
||||
}
|
||||
|
||||
@@ -8388,14 +8625,14 @@ Pocketing::CalcBoundedSmootedLink( const Point3d& ptStart, const Vector3d& vtSta
|
||||
return CalcBoundedLink( ptStart, ptEnd, vOffIslands, pCrvLink) ;
|
||||
|
||||
// controllo la distanza tra i due punti ( utilizzo raccordo lineare se grande)
|
||||
if ( SqDist( ptStart, ptEnd) > 3 * ( 4 * GetSideStep() + m_TParams.m_dDiam * m_TParams.m_dDiam)) {
|
||||
Point3d ptS_shift = ptStart + ( m_TParams.m_dDiam / 6) * vtStart ;
|
||||
Point3d ptE_shift = ptEnd - ( m_TParams.m_dDiam / 6) * vtEnd ;
|
||||
if ( SqDist( ptStart, ptEnd) > 25 * ( GetSideStep() + m_TParams.m_dDiam * m_TParams.m_dDiam)) {
|
||||
Point3d ptS_shift = ptStart + ( m_TParams.m_dDiam / 2) * vtStart ;
|
||||
Point3d ptE_shift = ptEnd - ( m_TParams.m_dDiam / 2) * vtEnd ;
|
||||
if ( ! CalcBoundedLink( ptS_shift, ptE_shift, vOffIslands, pCrvLink))
|
||||
return false ;
|
||||
pCrvLink->AddLine( ptStart, false) ;
|
||||
pCrvLink->AddLine( ptEnd, true) ;
|
||||
ModifyCurveToSmoothed( pCrvLink, m_TParams.m_dDiam / 16, m_TParams.m_dDiam / 16, false) ;
|
||||
ModifyCurveToSmoothed( pCrvLink, 2.5, 2.5, false) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -89,6 +89,12 @@ class Pocketing : public Machining
|
||||
bool SetPocketingVolume( const Point3d& ptInside, ISurfTriMesh* pStm) ;
|
||||
bool AdjustPocketingSideForVolumePart( ISurfTriMesh* pStmVolPart, const Vector3d& vtTool) ;
|
||||
bool SewingMissingFacesOnPlanes( ISurfTriMesh* pStm, const Plane3d& plPlane) ;
|
||||
bool ChainBisectors( ICURVEPOVECTOR& vpCrvs, ICRVCOMPOPOVECTOR& vCrvCompo) ;
|
||||
|
||||
// Dijkstra
|
||||
bool ChooseBestBisectorPath( ICRVCOMPOPOVECTOR& vCrvCompo, const Point3d& ptS,
|
||||
const Point3d& ptE, ICurveComposite* pCrvPath) ;
|
||||
|
||||
bool SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, ISURFFRPOVECTOR& vSrfSliced,
|
||||
std::vector<ICRVCOMPOPOVECTOR>& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec,
|
||||
VCT3DVECTOR& vVtTrasl, int& nStep, const Vector3d vtTool,
|
||||
@@ -257,7 +263,7 @@ class Pocketing : public Machining
|
||||
bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN,
|
||||
const ICurveComposite* pRCrv, bool bSplitArcs, bool bNoneForced,
|
||||
Point3d& ptP1, double& dElev, bool& bOppositeHome, bool bRecalcElev = true) ;
|
||||
bool CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const double& dSafeZ, const ISurfFlatRegion* pSfr,
|
||||
bool CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFlatRegion* pSfr,
|
||||
ICurveComposite* pCrvStepLink) ;
|
||||
double GetRadiusForStartEndElevation( void) const ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user