diff --git a/Pocketing.cpp b/Pocketing.cpp index 55dab33..9e2282e 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -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 pNextOffs ; - if ( ! vCrvStack.empty() && ( bOffsOk || dOffs < dTRad + EPS_ZERO)) { + PtrOwner 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 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 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 ; -} \ No newline at end of file diff --git a/Pocketing.h b/Pocketing.h index 8290fd8..f7f2889 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -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,