EgtMachKernel :

- in Pocketing::CalcSpiral modifica calcolo offset
- correzione errori nel calcolo della superficie lavorata
- correzione errori nel calcolo dei percorsi aggiuntivi.
This commit is contained in:
SaraP
2021-05-28 16:53:55 +02:00
parent 7e286c1c8e
commit d77102539a
2 changed files with 197 additions and 153 deletions
+193 -151
View File
@@ -3119,16 +3119,16 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
ICurveComposite* pMCrv, ICurveComposite* pRCrv)
{
ISurfFlatRegion * pCutRegion = CreateSurfFlatRegion() ; // regione lavorata
bool bFirst = false ;
bool bFirst = true ;
// inizializzo i risultati
pMCrv->Clear() ;
pRCrv->Clear() ;
// primo offset pari al raggio utensile + sovramateriale
double dTRad = 0.5 * m_TParams.m_dDiam ;
double dOffs = dTRad + GetOffsR() ;
// se circonferenza, chiamo la funzione specializzata
Point3d ptCen ; Vector3d vtN ; double dRad ; bool bCCW ;
if ( pCompo->IsACircle( 100 * EPS_SMALL, ptCen, vtN, dRad, bCCW)) {
@@ -3142,7 +3142,7 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
else
return true ;
}
// ciclo di offset verso l'interno
const int MAX_ITER = 1000 ;
int nIter = 0 ;
@@ -3158,7 +3158,7 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
while ( nIter < MAX_ITER) {
// calcolo
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( ( nIter == 0 ? (ICurve*) pCompo : pOffs), - dOffs, ICurve::OFF_FILLET) ||
if ( ( nIter == 0 || ! IsNull( pOffs)) && ! OffsCrv.Make( ( nIter == 0 ? (ICurve*) pCompo : pOffs), - dOffs, ICurve::OFF_FILLET) ||
( nIter == 0 && nReg == 0 && OffsCrv.GetCurveCount() == 0)) {
m_pMchMgr->SetLastError( 2412, "Error in Pocketing : Offset not computable") ;
return false ;
@@ -3169,10 +3169,10 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
// recupero le curve di offset e le metto sullo stack (se primo offset solo quella voluta)
int nCount = 0 ;
ICurve* pCrv = OffsCrv.GetLongerCurve() ;
bool bOffsOk = ( pCrv != nullptr) ; // indica se ho ottenuto un offset valido
while ( pCrv != nullptr) {
bool bOffsOk = ( pCrv != nullptr) ; // indica se ho ottenuto un offset valido nel caso in cui sia stato costruito
while ( pCrv != nullptr) {
if ( nIter != 0 || nReg == nCount) {
vCrvStack.emplace_back( pCrv) ;
vCrvStack.emplace_back( pCrv) ;
vRadStack.emplace_back( dCurrRad) ;
if ( nIter == 0)
break ;
@@ -3183,8 +3183,8 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
++ nCount ;
}
// recupero la prossima curva di offset se ho ottenuto un offset valido oppure ho fallito ma non è ulteriormente riducibile
PtrOwner<ICurve> pNextOffs ;
if ( ! vCrvStack.empty() && ( bOffsOk || dOffs < dTRad + EPS_ZERO)) {
PtrOwner<ICurve> pNextOffs ;
if ( ! vCrvStack.empty() && ( bOffsOk || dOffs < dTRad + EPS_ZERO)) {
pNextOffs.Set( Release( vCrvStack.back())) ;
vCrvStack.pop_back() ;
dCurrRad = vRadStack.back() ;
@@ -3195,39 +3195,39 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
bool bNextOk = ( dRad > EPS_ZERO && dRad < dCurrRad) ;
bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + GetOffsR() + EPS_ZERO : dOffs < dTRad + EPS_ZERO) ;
// se completato step di offset, accodo la curva offsettata al percorso di lavoro
if ( ! IsNull( pOffs) && ( bNextOk || bSmallRad)) {
// Superficie coperta dal tool quando percorre quell'offset ( senza tener conto delle parti aggiuntive)
ICurve * pCrvTmp = pOffs->Clone() ;
OffsetCurve OffsCrv2 ;
OffsCrv2.Make( pCrvTmp, m_TParams.m_dDiam/2, ICurve::OFF_FILLET) ;
ICurve * pCrvOff = OffsCrv2.GetLongerCurve() ;
// Superficie coperta dal tool quando percorre pOffs
OffsetCurve OffsCrvPlus ;
OffsCrvPlus.Make( pOffs, m_TParams.m_dDiam / 2 + 5 * EPS_SMALL, ICurve::OFF_FILLET) ;
ICurve * pCrvOffPlus = OffsCrvPlus.GetLongerCurve() ;
ISurfFlatRegion * pSrf = CreateSurfFlatRegion() ;
pSrf->AddExtLoop( pCrvOff) ;
OffsetCurve OffsCrv3 ;
OffsCrv3.Make( pCrvTmp, - m_TParams.m_dDiam/2, ICurve::OFF_FILLET) ;
ICurve * pCrvOff3 = OffsCrv3.GetLongerCurve() ;
while ( pCrvOff3 != nullptr) {
pSrf->AddIntLoop( pCrvOff3) ;
pCrvOff3 = OffsCrv3.GetCurve() ;
pSrf->AddExtLoop( pCrvOffPlus) ;
OffsetCurve OffsCrvMinus ;
OffsCrvMinus.Make( pOffs, - m_TParams.m_dDiam / 2 - 5 * EPS_SMALL, ICurve::OFF_FILLET) ;
ICurveComposite * pCrvOffMinus = GetCurveComposite( OffsCrvMinus.GetLongerCurve()) ;
while ( pCrvOffMinus != nullptr) {
if ( GetCurveRadius( pCrvOffMinus) > EPS_ZERO)
pSrf->AddIntLoop( pCrvOffMinus) ;
pCrvOffMinus = GetCurveComposite( OffsCrvMinus.GetCurve()) ;
}
if ( ! bFirst) {
bFirst = true ;
if ( bFirst) {
bFirst = false ;
pCutRegion = pSrf->Clone() ;
}
else {
else
pCutRegion->Add( *(pSrf->Clone())) ;
}
// inserisco l'offset nel vettore
vOffs.emplace_back( Release( pOffs)) ;
vOffs.emplace_back( Release( pOffs)) ;
}
// se offset va bene
if ( bNextOk) {
// sistemo per prossimo step
// sistemo per prossimo step
dCurrRad = dRad ;
pOffs.Set( GetCurveComposite( Release( pNextOffs))) ;
// nuovo valore pari allo step
@@ -3238,13 +3238,13 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
// nuovo valore pari al raggio
dOffs = ( nIter == 0 ? dTRad + GetOffsR() : dTRad) ;
}
// altrimenti esco
else
// altrimenti se non ho più curve da analizzare esco
else if ( vCrvStack.empty())
break ;
// incremento contatore iterazioni
++ nIter ;
}
// calcolo i collegamenti
ICURVEPOVECTOR vLinks( vOffs.size()) ;
for ( int i = 1 ; i < int( vOffs.size()) ; ++ i) {
@@ -3256,31 +3256,30 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
// calcolo il collegamento (garantendo che non esca dalla svuotatura)
PtrOwner<ICurveComposite> pCrvLink( CreateCurveComposite()) ;
if ( CalcBoundedLink( ptStart, ptEnd, vOffs[0], pCrvLink)) {
// Superficie coperta dal tool quando percorre il collegamento
pCrvLink->SetExtrusion( vtExtr) ;
const ICurve * pCrvTmp = pCrvLink->GetFirstCurve() ;
while ( pCrvTmp != nullptr) {
if ( pCrvTmp->GetType() == CRV_LINE) {
const ICurve * pCrvLinkTmp = pCrvLink->GetFirstCurve() ;
while ( pCrvLinkTmp != nullptr) {
if ( pCrvLinkTmp->GetType() == CRV_LINE) {
Point3d ptS, ptE ;
pCrvTmp->GetStartPoint( ptS) ;
pCrvTmp->GetEndPoint( ptE) ;
ICurveComposite * Crv2 = CreateCurveComposite() ;
Crv2->AddPoint( ptS) ;
Crv2->AddLine( ptE) ;
Crv2->AddLine( ptS) ;
Crv2->SetExtrusion( vtExtr) ;
pCrvLinkTmp->GetStartPoint( ptS) ;
pCrvLinkTmp->GetEndPoint( ptE) ;
ICurveComposite * pCrvTmp = CreateCurveComposite() ;
pCrvTmp->AddPoint( ptS) ;
pCrvTmp->AddLine( ptE) ;
pCrvTmp->AddLine( ptS) ;
pCrvTmp->SetExtrusion( vtExtr) ;
OffsetCurve OffsCrvPlus ;
OffsCrvPlus.Make( Crv2, m_TParams.m_dDiam/2, ICurve::OFF_FILLET) ;
OffsCrvPlus.Make( pCrvTmp, m_TParams.m_dDiam / 2 + 10 * EPS_SMALL, ICurve::OFF_FILLET) ;
ICurve * pCrvOffPlus = OffsCrvPlus.GetLongerCurve() ;
ISurfFlatRegion * pSrf = CreateSurfFlatRegion() ;
pSrf->AddExtLoop( pCrvOffPlus) ;
pCutRegion->Add( *(pSrf->Clone())) ;
}
pCrvTmp = pCrvLink->GetNextCurve() ;
pCrvLinkTmp = pCrvLink->GetNextCurve() ;
}
// Aggiungo il collegamento
vLinks[i].Set( Release( pCrvLink)) ;
}
@@ -3289,7 +3288,7 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
return false ;
}
}
// calcolo il percorso di ritorno
if ( vOffs.size() >= 2) {
// punti di inizio e fine
@@ -3302,7 +3301,7 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
if ( CalcBoundedLink( ptStart, ptEnd, vOffs[0], pCrvLink)) {
pRCrv->AddCurve( Release( pCrvLink)) ;
pRCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false) ;
// se necessario, approssimo archi con rette
// se necessario, approssimo archi con rette
if ( bSplitArcs && ! ApproxWithLines( pRCrv)) {
m_pMchMgr->SetLastError( 2421, "Error in Pocketing : Linear Approx not computable") ;
return false ;
@@ -3313,12 +3312,14 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
return false ;
}
}
// Verifico la presenza di aree non lavorate
if ( pCutRegion->GetLoopCount( 0) > 1 && ! RemoveUncutRegions( pCutRegion, vOffs))
}
// rimuovo aree non lavorate
if ( pCutRegion->GetLoopCount( 0) > 1 && ! RemoveUncutRegions( pCutRegion, vOffs)) {
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : removal of uncut regions failed") ;
return false ;
}
// creo il percorso di lavoro a partire dalla raccolta degli offset e dei collegamenti
for ( int i = 0 ; i < int( vOffs.size()) ; ++ i) {
// se collegamento da aggiungere
@@ -3332,7 +3333,7 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
// aggiungo la curva
pMCrv->AddCurve( Release( vOffs[i])) ;
}
// verifico il percorso di lavoro
if ( pMCrv->GetCurveCount() == 0) {
m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ;
@@ -3345,15 +3346,18 @@ Pocketing::CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
}
// eventuale sistemazione archi
VerifyArcs( pMCrv) ;
int id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCutRegion->Clone()) ;
m_pGeomDB->SetMaterial( id, Color(128,64,0,50)) ;
return true ;
return true ;
}
//----------------------------------------------------------------------------
bool
Pocketing::CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ICurve* pCrvBound,
ICurveComposite* pCrvLink)
{
{
// recupero il vettore estrusione
Vector3d vtExtr ;
pCrvBound->GetExtrusion( vtExtr) ;
@@ -3413,7 +3417,7 @@ Pocketing::CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const
}
}
}
pCrvLink->AddCurve( Release( pCompo)) ;
pCrvLink->AddCurve( Release( pCompo)) ;
return true ;
}
}
@@ -4174,58 +4178,63 @@ Pocketing::VerifyLeadInZigZag( const ICurveComposite* pCompo, const Point3d& ptP
return ( dMinDistPa > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL && dMinDistPb > 0.5 * m_TParams.m_dDiam - 10 * EPS_SMALL) ;
}
//----------------------------------------------------------------------------
bool
Pocketing::RemoveUncutRegions( const ISurfFlatRegion * pSTot, ICURVEPOVECTOR& vOffs)
{
{
// Conservo le curve vOffs originali in vettore Tmp da usare per i calcoli sui percorsi aggiuntivi
ICRVCOMPOPOVECTOR vOffsTmp( vOffs.size()) ;
for ( size_t i = 0 ; i < vOffs.size(); i++)
vOffsTmp[i].Set( GetCurveComposite( vOffs[i]->Clone())) ;
Vector3d vtExtr ;
vOffs[0]->GetExtrusion( vtExtr) ;
// Analizzo tutte le aree non lavorate
int nLoops = pSTot->GetLoopCount(0) ;
for ( size_t i = 1 ; i < nLoops ; i++) {
for ( size_t i = 1 ; i < nLoops ; i++) {
// Regione non lavorata
ICurveComposite * pResidualCrv = GetCurveComposite( pSTot->GetLoop( 0, i)) ;
ISurfFlatRegion * pResidualSrf = CreateSurfFlatRegion() ;
ISurfFlatRegion * pResidualSrf = CreateSurfFlatRegion() ;
pResidualCrv->Invert() ;
bool bAdd = pResidualSrf->AddExtLoop( pResidualCrv->Clone()) ;
// cerco la curva di vOffs su cui andrà il pezzo aggiuntivo e il punto in cui aggiungerlo
size_t idx ;
Point3d ptCrit, ptCen ;
if ( ! FindCurveForPathAdd( pResidualCrv, vOffs, idx, ptCrit))
return false ;
pResidualSrf->AddExtLoop( pResidualCrv->Clone()) ;
// verifico che area sia sufficientemente grande
double dArea ;
pResidualSrf->GetGrossArea( dArea) ;
if ( abs( dArea) < 10 * EPS_SMALL)
continue ;
pResidualCrv->GetCentroid( ptCen) ;
// cerco la curva di vOffs su cui andrà il percorso aggiuntivo
size_t idx ; // indice della curva in vOffs
Point3d ptCrit ; // punto in cui aggiungere il percorso extra
double dParCrit ; // parametro corrispondente a ptCrit
// Se ho angolo calcolo la lunghezza del primo tratto da aggiungere basandomi sull'angolo e sull'overlap
if ( ! FindCurveForPathAdd( pResidualCrv, vOffsTmp, idx, ptCrit, dParCrit, vOffs[0]))
return false ;
// Calcolo la lunghezza del primo tratto da aggiungere basandomi sull'angolo e sull'overlap
Point3d ptNew ;
bool bUsePtNew = false ;
double dParTmp ;
vOffsTmp[idx]->GetParamAtPoint( ptCrit, dParTmp) ;
// se sono su un vertice
if ( vOffsTmp[idx]->IsParamAtJoint( dParTmp)) {
const ICurve* pCrv1 = dParTmp < EPS_SMALL ? vOffsTmp[idx]->GetLastCurve() : vOffsTmp[idx]->GetCurve( round( dParTmp) - 1) ;
const ICurve* pCrv2 = vOffsTmp[idx]->GetCurve( round( dParTmp)) ;
// se il vertice è l'intersezione di due linee
bool bUsePtNew = false ;
// se sono sul punto di congiunzione fra due curve
if ( vOffsTmp[idx]->IsParamAtJoint( dParCrit)) {
const ICurve* pCrv1 = dParCrit < EPS_SMALL ? vOffsTmp[idx]->GetLastCurve() : vOffsTmp[idx]->GetCurve( round( dParCrit) - 1) ;
const ICurve* pCrv2 = vOffsTmp[idx]->GetCurve( round( dParCrit)) ;
// se le due cruve sono due linee
if ( pCrv1->GetType() == CRV_LINE && pCrv2->GetType() == CRV_LINE) {
// calcolo angolo formato dalle due linee
Vector3d vt1, vt2 ;
vOffsTmp[idx]->GetPointTang( dParTmp, ICurve::FROM_MINUS, Point3d(), vt1) ;
vOffsTmp[idx]->GetPointTang( dParTmp, ICurve::FROM_PLUS, Point3d(), vt2) ;
vOffsTmp[idx]->GetPointTang( dParCrit, ICurve::FROM_MINUS, Point3d(), vt1) ;
vOffsTmp[idx]->GetPointTang( dParCrit, ICurve::FROM_PLUS, Point3d(), vt2) ;
vt2.Invert() ;
double dCosAng = vt1 * vt2 ;
// calcolo lunghezza
// calcolo lunghezza basandomi sull'angolo e sull'overlap
double dAngSin = sqrt( (1 - dCosAng) / 2) ;
double dOverlap = 1 - GetSideStep() / m_TParams.m_dDiam ;
double dLen = ( m_TParams.m_dDiam / 2 - m_TParams.m_dDiam * dOverlap) / dAngSin - m_TParams.m_dDiam / 2 ;
Point3d ptCen ;
pResidualCrv->GetCentroid( ptCen) ;
Vector3d vtDir = ptCen - ptCrit ;
vtDir.Normalize() ;
ptNew = ptCrit + dLen * vtDir ;
@@ -4235,11 +4244,8 @@ Pocketing::RemoveUncutRegions( const ISurfFlatRegion * pSTot, ICURVEPOVECTOR& vO
// Percorso aggiuntivo
ICurveComposite * pAddPath = CreateCurveComposite() ;
pAddPath->AddPoint( ptCrit) ;
pAddPath->SetExtrusion( vtExtr) ; // setto estrusione corretta per farne offset
if ( ! ComputeAdditionalPath( pAddPath, pResidualSrf, ptNew, bUsePtNew))
return false ;
if ( ! ComputeAdditionalPath( ptCrit, ptNew, bUsePtNew, pAddPath, pResidualSrf, vOffsTmp[0]))
return false ;
// Nuova curva di offset con tratti aggiuntivi
PtrOwner<ICurveComposite> pNewOffs ;
@@ -4248,7 +4254,7 @@ Pocketing::RemoveUncutRegions( const ISurfFlatRegion * pSTot, ICURVEPOVECTOR& vO
vOffs[idx]->GetDomain( dParS, dParE) ;
vOffs[idx]->GetParamAtPoint( ptCrit, dPar) ;
pNewOffs->AddCurve( vOffs[idx]->CopyParamRange( dParS, dPar)) ; // fino al punto critico è il vecchio offset
pNewOffs->AddCurve( pAddPath->Clone()) ; // al punto critico aggiungo il nuovo percorso
pNewOffs->AddCurve( pAddPath->Clone()) ; // al punto critico aggiungo il nuovo percorso
if ( abs( dPar - dParS) > EPS_SMALL && abs( dPar - dParE) > EPS_SMALL)
pNewOffs->AddCurve( vOffs[idx]->CopyParamRange( dPar, dParE)) ; // aggiungo la parte rimanente del vecchio offset
@@ -4260,87 +4266,123 @@ Pocketing::RemoveUncutRegions( const ISurfFlatRegion * pSTot, ICURVEPOVECTOR& vO
//----------------------------------------------------------------------------
bool
Pocketing::FindCurveForPathAdd( const ICurveComposite * pCrv, const ICURVEPOVECTOR& vOffs, size_t& idxMin, Point3d& ptMinDist)
Pocketing::FindCurveForPathAdd( const ICurveComposite * pCrv, const ICRVCOMPOPOVECTOR& vOffs, size_t& nIdxMin, Point3d& ptMinDist,
double& dMinDistPar, const ICurve * pCrvBound)
{
idxMin = -1 ;
nIdxMin = -1 ;
Point3d ptCen ;
pCrv->GetCentroid( ptCen) ;
double distMin = INFINITO ;
double dist ;
double dDistMin = INFINITO ;
double dDist ;
for ( size_t i = 0 ; i < vOffs.size() ; i ++) {
// verifico se la regione da rimuovere ( pCrv) è esterna alla regione racchiusa da vOffs
ISurfFlatRegion * pSrf = CreateSurfFlatRegion() ;
pSrf->AddExtLoop( vOffs[i]->Clone()) ;
CRVCVECTOR ccClass ;
pSrf->GetCurveClassification( *pCrv, ccClass) ;
pSrf->AddExtLoop( vOffs[i]->Clone()) ;
if ( ccClass.size() != 1)
return false ;
CRVCVECTOR ccClass ;
if ( ! pSrf->GetCurveClassification( *pCrv, ccClass))
continue ;
if ( ccClass.size() != 1)
return false ;
// se è esterna calcolo la sua distanza dal centro della regione da rimuovere
if ( ccClass[0].nClass == CRVC_OUT) {
DistPointCurve distPtCrv( ptCen, *(vOffs[i]->Clone())) ;
if ( distPtCrv.GetDist( dist) && dist < distMin) {
distMin = dist ;
idxMin = i ;
int nFlag ;
distPtCrv.GetMinDistPoint( 0, ptMinDist, nFlag) ;
// versione 1 : trovo il punto di vOffs[i] a distanza minima da ptCen
// DistPointCurve distPtCrv( ptCen, *(vOffs[i]->Clone())) ;
// if ( distPtCrv.GetDist( dist) && dist < distMin) {
// distMin = dist ;
// idxMin = i ;
// int nFlag ;
// distPtCrv.GetMinDistPoint( 0, ptMinDist, nFlag) ;
// }
// versione 2 : trovo il punto di congiunzione di due curve di vOffs[i] a distanza minima da ptCen, dove la distanza
// non è calcolata lungo una linea retta, ma tenendo conto che deve restare sempre all'interno della regione da svuotare
double dParS, dParE ;
vOffs[i]->GetDomain( dParS, dParE) ;
// scorro tutti i vertici ( i punti di congiunzione di due curve)
for ( int j = dParS ; j < dParE ; j ++) {
ICurveComposite * pLinkPath = CreateCurveComposite() ;
Point3d ptCrv ;
vOffs[i]->GetPointD1D2( j, ICurve::FROM_MINUS, ptCrv) ;
// calcolo la distanza come il percorso inerno alla regione che li congiunge
CalcBoundedLink( ptCrv, ptCen, pCrvBound, pLinkPath) ;
double dLen ;
if ( pLinkPath->GetLength( dLen) && dLen < dDistMin) {
dDistMin = dLen ;
nIdxMin = i ;
ptMinDist = ptCrv ;
dMinDistPar = j ;
}
}
}
}
// se la regione da rimuovere ( pCrv) è interna a tutte le curve di offset errore
if ( idxMin == -1 )
if ( nIdxMin == -1 )
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
Pocketing::ComputeAdditionalPath( ICurveComposite * pAddPath, ISurfFlatRegion * pResidualSrf, Point3d ptNew, bool bUsePtNew)
{
if ( ! bUsePtNew)
pResidualSrf->GetCentroid( ptNew) ;
//----------------------------------------------------------------------------
bool
Pocketing::ComputeAdditionalPath( const Point3d ptStart, Point3d ptEnd, bool bUsePtEnd, ICurveComposite * pAddPath,
ISurfFlatRegion * pResidualSrf, const ICurveComposite * pCrvBound)
{
// verifico che area non sia troppo piccola
double dArea ;
if ( pResidualSrf->GetGrossArea( dArea) && abs( dArea) < EPS_SMALL)
return true ;
// Aggiungo il nuovo tratto al percorso
pAddPath->AddLine( ptNew) ;
if ( ! bUsePtEnd) {
pResidualSrf->GetCentroid( ptEnd) ;
}
Vector3d vtExtr ;
pAddPath->GetExtrusion( vtExtr) ;
// creo il percorso fra ptStart e ptEnd senza uscire dalla svuotatura
CalcBoundedLink( ptStart, ptEnd, pCrvBound, pAddPath) ;
ICurveComposite * pReturnPath = pAddPath->Clone() ; // percorso di ritorno
pReturnPath->Invert() ;
// Area coperta dal nuovo pezzo aggiunto
ICurveComposite * pAddPathTmp = CreateCurveComposite() ;
Point3d ptS ;
pAddPath->GetStartPoint( ptS) ;
pAddPathTmp->AddPoint( ptS) ;
pAddPathTmp->AddLine( ptNew) ;
pAddPathTmp->AddLine( ptS) ;
pAddPathTmp->SetExtrusion( vtExtr) ;
OffsetCurve OffsCrv ;
OffsCrv.Make( pAddPathTmp, m_TParams.m_dDiam / 2, ICurve::OFF_FILLET) ;
ICurve * pCrvOffs = OffsCrv.GetLongerCurve() ;
ISurfFlatRegion * pToolSrf = CreateSurfFlatRegion() ;
pToolSrf->AddExtLoop( pCrvOffs) ;
// Area coperta dal nuovo tratto aggiuntivo
ICurveComposite * pAddPathTmp = CreateCurveComposite() ;
pAddPathTmp->AddPoint( ptStart) ;
pAddPathTmp->AddCurve( pAddPath->Clone()) ;
pAddPathTmp->AddCurve( pReturnPath->Clone()) ;
pAddPathTmp->SetExtrusion( pResidualSrf->GetNormVersor()) ; // setto estrusione per l'offset in modo da essere compatibile con quella di ResidualSrf
OffsetCurve OffsCrv ;
OffsCrv.Make( pAddPathTmp, m_TParams.m_dDiam / 2 + 10 * EPS_SMALL, ICurve::OFF_FILLET) ;
ICurve * pCrvOffs = OffsCrv.GetLongerCurve() ;
ISurfFlatRegion * pToolSrf = CreateSurfFlatRegion() ;
pToolSrf->AddExtLoop( pCrvOffs) ;
// m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pToolSrf->Clone()) ;
// m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pAddPathTmp->Clone()) ;
// m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvOffs->Clone()) ;
// Se tutta l'area è stata lavorata
if ( ! pResidualSrf->Subtract( *pToolSrf) || pResidualSrf == nullptr) {
pAddPath->AddLine( ptS) ; // percorso di ritorno
return true ;
}
// int id = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pResidualSrf->Clone()) ;
// LOG_ERROR( GetEMkLogger(), ("id " + to_string(id)).c_str()) ;
// m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pToolSrf->Clone()) ;
// Scorro tutte le regioni non lavorate rimaste
for ( size_t i = 0 ; i < pResidualSrf->GetChunkCount() ; i++) {
ICurveComposite * pNewAddPath = CreateCurveComposite() ;
pNewAddPath->SetExtrusion( vtExtr) ;
pNewAddPath->AddPoint( ptNew) ;
ComputeAdditionalPath( pNewAddPath, pResidualSrf->CloneChunk( i), ptNew, false) ;
pAddPath->AddCurve( pNewAddPath->Clone()) ;
}
if ( ! pResidualSrf->Subtract( *pToolSrf) )
return false ;
pAddPath->AddLine( ptS) ; // percorso di ritorno
if ( pResidualSrf != nullptr && pResidualSrf->IsValid()) {
// Scorro tutte le regioni non lavorate rimaste
for ( size_t i = 0 ; i < pResidualSrf->GetChunkCount() ; i++) {
ICurveComposite * pNewAddPath = CreateCurveComposite() ;
ComputeAdditionalPath( ptEnd, Point3d(), false, pNewAddPath, pResidualSrf->CloneChunk( i), pCrvBound) ;
pAddPath->AddCurve( pNewAddPath->Clone()) ;
}
}
pAddPath->AddCurve( pReturnPath->Clone()) ; // percorso di ritorno
return true ;
}
return true ;
}
+4 -2
View File
@@ -88,8 +88,10 @@ class Pocketing : public Machining
bool CalcSpiral( const ICurveComposite* pCompo, int nReg, bool bSplitArcs,
ICurveComposite* pMCrv, ICurveComposite* pRCrv) ;
bool RemoveUncutRegions( const ISurfFlatRegion * pSTot, ICURVEPOVECTOR& vOffs) ;
bool FindCurveForPathAdd( const ICurveComposite * pCrvLoop, const ICURVEPOVECTOR& vOffs, size_t& idxMin, Point3d& ptMinDist) ;
bool ComputeAdditionalPath( ICurveComposite * pAddPath, ISurfFlatRegion * pResidualSrf, Point3d ptNew, bool bUsePtNew) ;
bool FindCurveForPathAdd( const ICurveComposite * pCrv, const ICRVCOMPOPOVECTOR& vOffs, size_t& nIdxMin, Point3d& ptMinDist,
double& dMinDistPar, const ICurve * pCrvBound) ;
bool ComputeAdditionalPath( const Point3d ptStart, Point3d ptNew, bool bUsePtEnd, ICurveComposite * pAddPath,
ISurfFlatRegion * pResidualSrf, const ICurveComposite * pCrvBound) ;
bool CalcBoundedLink( const Point3d& ptStart, const Point3d& ptEnd, const ICurve* pCrvBound,
ICurveComposite* pCrvLink) ;
bool CalcCircleSpiral( const Point3d& ptCen, const Vector3d& vtN, double dOutRad, double dIntRad,