From ac8feb7a17531eec61433d3ad66bcfb3eca70cc3 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Thu, 11 Jan 2024 17:57:23 +0100 Subject: [PATCH] EgtMachKernel : - utilizzo della funzione limite per LeadIn/Out. --- Pocketing.cpp | 307 +++++++++++++++++++++++++++++++------------------- Pocketing.h | 10 +- 2 files changed, 196 insertions(+), 121 deletions(-) diff --git a/Pocketing.cpp b/Pocketing.cpp index 1beda29..3f21b3f 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -2296,9 +2296,11 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) vector vCrvOEWithFlags; // vettore delle relative curve originali ( per ogni step) BOOLVECTOR vbChangedPrec( nStep, false) ; // vettore di Flag per superfici uguali tra steps consecutivi VCT3DVECTOR vVtTrasl( nStep, V_NULL) ; // vettore contenente le quote per le passate di svuotature + ISURFFRPOVECTOR vSrfLimit ; // vettore delle superfici limite // ricavo le superfici di svuotatura - if ( ! SliceVolume( pStm_PartVolume, pStm_Part, vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, nStep, vtTool, dElev, dDepth, dStep)) + if ( ! SliceVolume( pStm_PartVolume, pStm_Part, vSrfSliced, vSrfLimit, vCrvOEWithFlags, + vbChangedPrec, vVtTrasl, nStep, vtTool, dElev, dDepth, dStep)) return false ; // riporto il volume nel frame globale @@ -2308,22 +2310,28 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) for ( int s = 0 ; s < int( vSrfSliced.size()) ; ++ s) vSrfSliced[s]->ToGlob( frElevation) ; - for ( int s = 0 ; s < int( vSrfSliced.size()) ; ++ s) { - PtrOwner pSrf_toDraw( CloneSurfFlatRegion( vSrfSliced[s])) ; - int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ; - m_pGeomDB->SetMaterial( a, Color( 0.0, 0.0, 1.0, 0.45)) ; - for ( int c = 0 ; c < pSrf_toDraw->GetChunkCount() ; ++ c) { - for ( int l = 0 ; l < pSrf_toDraw->GetLoopCount( c) ; ++ l) { - PtrOwner pCrvCompo( GetCurveComposite( pSrf_toDraw->GetLoop( c, l))) ; - for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { - int nProp0 ; pCrvCompo->GetCurveTempProp( u, nProp0, 0) ; - int nProp1 ; pCrvCompo->GetCurveTempProp( u, nProp1, 1) ; - int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ; - m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ; + // riporto le superfici limite nel frame globale + for ( int s = 0 ; s < int( vSrfLimit.size()) ; ++ s) + vSrfLimit[s]->ToGlob( frElevation) ; + + for ( int s = 0 ; s < int( vSrfLimit.size()) ; ++ s) { + if ( ! vSrfLimit[s]->IsValid()) + continue ; + PtrOwner pSrf_toDraw( CloneSurfFlatRegion( vSrfLimit[s])) ; + int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSrf_toDraw->Clone()) ; + m_pGeomDB->SetMaterial( a, Color( 0.0, 0.0, 1.0, 0.45)) ; + /*for ( int c = 0 ; c < pSrf_toDraw->GetChunkCount() ; ++ c) { + for ( int l = 0 ; l < pSrf_toDraw->GetLoopCount( c) ; ++ l) { + PtrOwner pCrvCompo( GetCurveComposite( pSrf_toDraw->GetLoop( c, l))) ; + for ( int u = 0 ; u < pCrvCompo->GetCurveCount() ; ++ u) { + int nProp0 ; pCrvCompo->GetCurveTempProp( u, nProp0, 0) ; + int nProp1 ; pCrvCompo->GetCurveTempProp( u, nProp1, 1) ; + int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvCompo->GetCurve( u)->Clone()) ; + m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ; + } } - } - } - } + }*/ + } // riporto le curve per i casi ottimizzati nel frame globale @@ -2348,7 +2356,7 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId) return false ; break ; case POCKET_SUB_SPIRALIN : - if ( ! AddSpiralIn( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vtTool, vtTool, dDepth, dElev, + if ( ! AddSpiralIn( vSrfSliced, vCrvOEWithFlags, vbChangedPrec, vVtTrasl, vSrfLimit, vtTool, vtTool, dDepth, dElev, dMaxElev, dOkStep, bSplitArcs)) return false ; break ; @@ -2417,7 +2425,7 @@ Pocketing::GetProjectionOfStmToNotPocket( const ISurfTriMesh* pStmPart, const IS //---------------------------------------------------------------------------- bool Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, ISURFFRPOVECTOR& vSrfSliced, - std::vector& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec, + ISURFFRPOVECTOR& vSfrLimit, std::vector& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec, VCT3DVECTOR& vVtTrasl, int& nStep, const Vector3d vtTool, const double dElev, const double dDepth, const double dStep) { @@ -2437,6 +2445,7 @@ Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Pa // aggirno le dimensioni dei vettori da restituire in base agli step calcolati vSrfSliced.clear() ; vSrfSliced.resize( int( vVtTrasl.size())) ; + vSfrLimit.clear() ; vSfrLimit.resize( int( vVtTrasl.size())) ; vCrvOEWithFlags.clear() ; vCrvOEWithFlags.resize( int( vVtTrasl.size())) ; vbChangedPrec.clear() ; vbChangedPrec.resize( int( vVtTrasl.size())) ; @@ -2479,6 +2488,8 @@ Pocketing::SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Pa return false ; // inserisco la superficie nel vettore vSrfSliced[j-1].Set( Release( pSfrCurr)) ; + // inserisco la superficie limite nel vettore + vSfrLimit[j-1].Set( Release( pSfrLimit)) ; // controllo se la superficie è uguale a quella inserita nello step precedente // ... W.I.P ... vbChangedPrec[j-1] = true ; @@ -3227,6 +3238,12 @@ Pocketing::ModifySurfByOpenEdges( ISurfFlatRegion* pSfr, const ISurfFlatRegion* m_dDiam_Prec > 0 ? m_dOffsetR_Prec : GetOffsR(), m_dDiam_Prec > 0 ? m_dSideStep_Prec : GetSideStep(), pSfrLimit)) { + for ( int u = 0 ; u < pCrvEL->GetCurveCount() ; ++ u) { + int nProp0 ; pCrvEL->GetCurveTempProp( u, nProp0, 0) ; + int nProp1 ; pCrvEL->GetCurveTempProp( u, nProp1, 1) ; + int aaa = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvEL->GetCurve( u)->Clone()) ; + m_pGeomDB->SetMaterial( aaa, nProp0 == 0 ? BLUE : RED) ; + } m_pMchMgr->SetLastError( 2430, "Error in Pocketing : adjust open edges failed") ; return false ; } @@ -5727,7 +5744,7 @@ Pocketing::AddOneWay( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, - VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, + VCT3DVECTOR& vVtTrasl, ISURFFRPOVECTOR& vSrfLimit, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) { // recupero distanze di sicurezza @@ -5969,8 +5986,8 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector& if ( IsNull( pCurve)) return false ; - int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCurve->Clone()) ; - m_pGeomDB->SetMaterial( b, RED) ; + //int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCurve->Clone()) ; + //m_pGeomDB->SetMaterial( b, RED) ; // se prima curva del percorso if ( u == 0) { @@ -6027,13 +6044,13 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector& Point3d ptDest ; vMCrv[i]->GetStartPoint( ptDest) ; // calcolo il percorso di ritorno del percorso attuale if ( IsNull( pRCrv) || - ! CalcLinkOnStep( ptCurr, ptDest, vSfr[j-2], pRCrv)) { + ! CalcLinkOnStep( ptCurr, ptDest, vSfr[j-2], vSrfLimit[j-2], pRCrv)) { m_pMchMgr->SetLastError( 2413, "Error in Pocketing : Toolpath not computable") ; return false ; } // emetto - int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pRCrv->Clone()) ; - m_pGeomDB->SetMaterial( b, BLUE) ; + //int b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pRCrv->Clone()) ; + //m_pGeomDB->SetMaterial( b, BLUE) ; SetFeed( GetEndFeed()) ; if ( pRCrv->GetCurveCount() > 0 && AddCurveMove( pRCrv) == GDB_ID_NULL) return false ; @@ -6110,7 +6127,7 @@ Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector& //---------------------------------------------------------------------------- bool Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFlatRegion* pSfr, - ICurveComposite* pCrvStepLink) + const ISurfFlatRegion* pSfrLimit, ICurveComposite* pCrvStepLink) { // ptS -> punto finale del percorso attuale di pocketing // ptE -> punto iniziale del successivo percorso di pocketing @@ -6124,21 +6141,11 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl return false ; pCrvStepLink->Clear() ; - // prendo la regione ed Offsetto internamente per ricavare la regione sicura dove posso muovermi - PtrOwner pSfrSafe( pSfr->CreateOffsetSurf( - 0.5 * m_TParams.m_dDiam - GetOffsR() + 5 * EPS_SMALL, - ICurve::OFF_FILLET)) ; - if ( IsNull( pSfrSafe) || ! pSfrSafe->IsValid()) - return false ; - // creo un sistema di riferimento centrato nella regione Frame3d frCurr ; frCurr.Set( ptS, pSfr->GetNormVersor()) ; if ( ! frCurr.IsValid()) return false ; - - // porto la supercie Safe nel riferimento creato - pSfrSafe->ToLoc( frCurr) ; - // ricavo il punto finale proiettato sul piano Z = 0 ( quello di svuotatura attuale) Point3d ptEProj = ptE ; ptEProj.ToLoc( frCurr) ; ptEProj.z = 0 ; @@ -6148,61 +6155,40 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl // creo un Segmento tra l'ORIG ( ptS) e la proiezione del punto finale PtrOwner pSeg( CreateCurveLine()) ; - if ( IsNull( pSeg) || - ! pSeg->Set( ORIG, ptEProj) || - ! pSeg->IsValid()) + if ( IsNull( pSeg) || ! pSeg->Set( ORIG, ptEProj) || ! pSeg->IsValid()) return false ; - // se il segmento è tutto interno alla regione Safe... + // controllo se tale tratto lineare è ammissibile, potrei uscire presso un lato aperto + // o attraversare la regione di svuotatura in parti che non vanno svuotate ( ad esempio isole o + // rientranze di contorni chiusi ) -> controllo la superficie limite ( offsettata del raggio del tool) + bool bIsAllSecure = ! pSfrLimit->IsValid() ; CRVCVECTOR ccClass ; - if ( ! pSfrSafe->GetCurveClassification( *pSeg, EPS_SMALL, ccClass) || - ccClass.empty()) + PtrOwner pSfrDanger( pSfrLimit->CreateOffsetSurf( 0.5 * m_TParams.m_dDiam + 5 * EPS_SMALL, + ICurve::OFF_FILLET)) ; + if ( ! bIsAllSecure && + ( IsNull( pSfrDanger) || ! pSfrDanger->IsValid() || ! pSfrDanger->ToLoc( frCurr) || + ! pSfrDanger->GetCurveClassification( *pSeg, EPS_SMALL, ccClass) || ccClass.empty() || + ! pSfrDanger->ToGlob( frCurr))) return false ; - if ( int( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_IN) - // creo il tratto lineare leggermente rialzato + if ( bIsAllSecure || ( ccClass.size()) == 1 && ccClass[0].nClass == CRVC_OUT) return pCrvStepLink->AddPoint( ORIG) && pCrvStepLink->AddLine( ORIG + SAFE_Z_RET * Z_AX) && pCrvStepLink->AddLine( ptEProj + SAFE_Z_RET * Z_AX) && pCrvStepLink->IsValid() && pCrvStepLink->ToGlob( frCurr) ; + // in questo caso sto rovinando delle parti di grezzo : le scelte ora sono 2 + // 1) cerco un percorso ammissibile con i bisettori ( MedialAxis da Voroni ) + // 2) Scarico - - // se invece esistono intersezioni devo prendere in considerazione i tratti esterni alla regione - // originaria, l'elevazione è calcolata sui tratti esterni ad essa - double dMAxElev = 0. ; - ccClass.clear() ; - PtrOwner pSfrCurr( CloneSurfFlatRegion( pSfr)) ; - if ( IsNull( pSfrCurr) || ! pSfrCurr->IsValid() || - ! pSfrCurr->ToLoc( frCurr) || - ! pSfrCurr->GetCurveClassification( *pSeg, EPS_SMALL, ccClass)) - return false ; - for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) { - if ( ccClass[i].nClass == CRVC_IN) - continue ; - Point3d ptS_i, ptE_i ; - if ( ! pSeg->GetPointD1D2( ccClass[i].dParS, ICurve::FROM_MINUS, ptS_i) || - ! pSeg->GetPointD1D2( ccClass[i].dParE, ICurve::FROM_PLUS, ptE_i)) - return false ; - double dElev = 0. ; - ptS_i.ToGlob( frCurr) ; - ptE_i.ToGlob( frCurr) ; - if ( ! GetElevation( m_nPhase, ptS_i, ptE_i, pSfr->GetNormVersor(), m_TParams.m_dDiam * 0.5, m_TParams.m_dLen, - pSfr->GetNormVersor(), dElev)) - return false ; - dMAxElev = max( dMAxElev, dElev) ; - } - // 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 + SAFE_Z_RET * Z_AX) && - pCrvStepLink->AddLine( ptEProj + SAFE_Z_RET * Z_AX) && - pCrvStepLink->IsValid() && - pCrvStepLink->ToGlob( frCurr) ; - - // in questo caso creo un percorso con i Bisettori seguendo VRONI + // 1) ricavo i bisettori dell'Offset interno del raggio della regione da svuotare ( ed eventuale offset radiale) + // ( I Bisettori sono quindi accorciati presso i loro estremi ) ICURVEPOVECTOR vCrvBisectors ; - Voronoi* pVRONI( pSfr->GetVoronoiObject()) ; + PtrOwner pSfrSafe( pSfr->CreateOffsetSurf( - 0.5 * m_TParams.m_dDiam - GetOffsR() - 5 * EPS_SMALL, + ICurve::OFF_FILLET)) ; + if ( IsNull( pSfrSafe) || ! pSfrSafe->IsValid()) + return false ; + Voronoi* pVRONI( pSfrSafe->GetVoronoiObject()) ; if ( pVRONI == nullptr || ! pVRONI->CalcMedialAxis( vCrvBisectors, Voronoi::WMAT_LEFT) || vCrvBisectors.empty()) @@ -6211,53 +6197,47 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl // 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 + // calcolo il percorso ottimale ( Dijkstra) PtrOwner pCrvPath( CreateCurveComposite()) ; if ( IsNull( pCrvPath) || ! ChooseBestBisectorPath( vCompoBisChain, ORIG, ptEProj, pCrvPath)) return false ; - + + double dMAxElev = 0. ; + // controllo che la curva si effettivamente valida e distante dal percorso, altrimenti scarico bool bSkip = ! pCrvPath->IsValid() || pCrvPath->GetCurveCount() == 0 ; - - for ( int j = 0 ; j < int( pCrvPath->GetCurveCount()) && ! 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) { // calcolo i tratti lineari di raccordo tra il percorso trovato e i punti iniziali e finali effettivi Point3d ptS_path, ptE_path ; if ( ! pCrvPath->GetStartPoint( ptS_path) || ! pCrvPath->GetEndPoint( ptE_path)) return false ; - CRVCVECTOR ccClass_line ; + if ( ! AreSamePointEpsilon( ptS_path, ORIG, 5 * EPS_SMALL)) { - PtrOwner pLineToStart( CreateCurveLine()) ; - if ( IsNull( pLineToStart) || - ! pLineToStart->Set( ORIG, ptS_path) || - ! pSfrSafe->GetCurveClassification( *pLineToStart, EPS_SMALL, ccClass_line)) + PtrOwner pSegStart( CreateCurveLine()) ; + if ( IsNull( pSegStart) || ! pSegStart->Set( ORIG, ptS_path) || ! pSegStart->IsValid() || + ! pSegStart->ToGlob( frCurr) || ! GetSpecialElevation( pSfrDanger, pSegStart, true, dMAxElev)) return false ; - bSkip = ! ( int( ccClass_line.size()) == 1 && ccClass_line[0].nClass == CRVC_IN) ; + bSkip = ( dMAxElev > EPS_SMALL) ; } if ( ! bSkip) { - ccClass_line.clear() ; if ( ! AreSamePointEpsilon( ptE_path, ptEProj, 5 * EPS_SMALL)) { - PtrOwner pLineToEnd( CreateCurveLine()) ; - if ( IsNull( pLineToEnd) || - ! pLineToEnd->Set( ptEProj, ptE_path) || - ! pSfrSafe->GetCurveClassification( *pLineToEnd, EPS_SMALL, ccClass_line)) + PtrOwner pSegEnd( CreateCurveLine()) ; + if ( IsNull( pSegEnd) || ! pSegEnd->Set( ptEProj, ptE_path) || ! pSegEnd->IsValid() || + ! pSegEnd->ToGlob( frCurr) || ! GetSpecialElevation( pSfrDanger, pSegEnd, true, dMAxElev)) return false ; - bSkip = ! ( int( ccClass_line.size()) == 1 && ccClass_line[0].nClass == CRVC_IN) ; + bSkip = ( dMAxElev > EPS_SMALL) ; } } } - - // se la curva non è valida, non sufficientemente lontana dal bordo della regione Safe o i raccordi + // se la curva non è valida, ovvero non è sufficientemente lontana dal bordo della regione Safe o i raccordi // lineari rovinano il grezzo, scarico if ( bSkip) return pCrvStepLink->AddPoint( ORIG) && @@ -6266,7 +6246,7 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl ( 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) ; @@ -6276,20 +6256,21 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl 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) ; + //pCrvPath->MergeCurves( 100 * EPS_SMALL, 100 * EPS_ANG_SMALL) ; + //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) + // 2) valuto se invece è più conveniente scaricare ( quindi alzandomi dell'elevazione sopra alla linea) // la lunghezza del tratto in salita e in discesa è dMaxElev // la lunghezza del tratto orizzontale è data dalla distanza tra ORIG e ptEProj + if ( ! pSeg->ToGlob( frCurr) || + ! GetSpecialElevation( pSfrDanger, pSeg, false, dMAxElev)) + return false ; + if ( dCurrLen < 2 * dMAxElev + Dist( ORIG, ptEProj)) // privilegio il percorso return pCrvStepLink->AddPoint( ORIG) && @@ -6308,6 +6289,67 @@ Pocketing::CalcLinkOnStep( const Point3d& ptS, const Point3d& ptE, const ISurfFl pCrvStepLink->ToGlob( frCurr) ; } +//---------------------------------------------------------------------------- +bool +Pocketing::GetSpecialElevation( const ISurfFlatRegion* pSfr, const ICurveLine* pLine, const bool bInVsOut, + double& dElev) +{ + // calcolo dell'elevazione sopra alle parti di pLine che si trovano all'interno dalla pSfr + + // controllo dei parametri + if ( pSfr == nullptr || ! pSfr->IsValid() || + pLine == nullptr || ! pLine->IsValid()) + return false ; + + dElev = 0. ; + + // creo il frame per classificare le curve nel piano XY + Frame3d frCurr ; + Point3d ptC ; pLine->GetStartPoint( ptC) ; + frCurr.Set( ptC, pSfr->GetNormVersor()) ; + if ( ! frCurr.IsValid()) + return false ; + + // classificazione + CRVCVECTOR ccClass ; + PtrOwner pSfrCurr( CloneSurfFlatRegion( pSfr)) ; + PtrOwner pSeg( CloneCurveLine( pLine)) ; + if ( IsNull( pSfrCurr) || ! pSfrCurr->IsValid() || + IsNull( pSeg) || ! pSeg->IsValid() || + ! pSfrCurr->ToLoc( frCurr) || ! pSeg->ToLoc( frCurr) || + ! pSfrCurr->GetCurveClassification( *pSeg, EPS_SMALL, ccClass)) + return false ; + + int r = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfr->Clone()) ; + m_pGeomDB->SetMaterial( r, Color( 0.0, 1., 0., 0.15)) ; + r = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pLine->Clone()) ; + m_pGeomDB->SetMaterial( r, BLACK) ; + + // per ogni tratto non esterno, calcolo la sua elevazione + for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) { + if (( bInVsOut && ccClass[i].nClass != CRVC_OUT) || + ( ! bInVsOut && ccClass[i].nClass != CRVC_IN)) { + Point3d ptS_i, ptE_i ; + if ( ! pSeg->GetPointD1D2( ccClass[i].dParS, ICurve::FROM_MINUS, ptS_i) || + ! pSeg->GetPointD1D2( ccClass[i].dParE, ICurve::FROM_PLUS, ptE_i)) + return false ; + double dCurrElev = 0. ; + ptS_i.ToGlob( frCurr) ; // in globale + ptE_i.ToGlob( frCurr) ; // in globale + ICurveLine* pLineX( CreateCurveLine()) ; pLineX->Set( ptS_i, ptE_i) ; + int r = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pLineX->Clone()) ; + m_pGeomDB->SetMaterial( r, RED) ; + if ( ! GetElevation( m_nPhase, ptS_i, ptE_i, pSfr->GetNormVersor(), m_TParams.m_dDiam * 0.5, m_TParams.m_dLen, + pSfr->GetNormVersor(), dCurrElev)) + return false ; + + dElev = max( dCurrElev, dElev) ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool Pocketing::ChooseBestBisectorPath( ICRVCOMPOPOVECTOR& vCrvCompo, const Point3d& ptS, @@ -6397,10 +6439,10 @@ Pocketing::ChooseBestBisectorPath( ICRVCOMPOPOVECTOR& vCrvCompo, const Point3d& } } - 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) ; - } + //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) ; + //} // definizioni per l'albero su cui calcolare i percorsi minimi struct Link { @@ -9931,8 +9973,13 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE if ( AreOppositeVectorApprox( pSfrBean->GetNormVersor(), pSfrInc->GetNormVersor())) pSfrBean->Invert() ; // 10) aggiorno la regione di incidenza - if ( ! pSfrInc->Add( *pSfrBean)) + if ( ! pSfrInc->Add( *pSfrBean)) { + int o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrInc->Clone()) ; + m_pGeomDB->SetMaterial( o, ORANGE) ; + o = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pSfrBean->Clone()) ; + m_pGeomDB->SetMaterial( o, RED) ; return false ; + } } pOffLongestCrv.Set( OffsCrv.GetLongerCurve()) ; } @@ -9948,9 +9995,34 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE // L'algoritmo di allargamento presso i lati aperti è Euristico; io mi estendo a seconda della geometria del // lato aperto al di fuori del volume di svuotatura... Devo controllare di non rovinare delle zone al di fuori di // esso ! - if ( pSfrLimit->IsValid()) + if ( pSfrLimit->IsValid()) { if ( ! pSfrInc->Subtract( *pSfrLimit)) return false ; + // può capitare che la regione Limite mi crei più Chunk sulla pSfrInc + // I chunk da togliere sono tutti quelli che si sono separati dalla pCrvBorder + if ( pSfrInc->GetChunkCount() > 1) { + PtrOwner pNewSfrInc( CreateSurfFlatRegion()) ; + if ( IsNull( pNewSfrInc)) + return false ; + Point3d ptS, ptE ; + if ( ! pCrvBorder->GetStartPoint( ptS) || ! pCrvBorder->GetEndPoint( ptE)) + return false ; + for ( int i = 0 ; i < pSfrInc->GetChunkCount() ; ++ i) { + PtrOwner pCrvEL( ConvertCurveToComposite( pSfrInc->GetLoop( i, 0))) ; + if ( IsNull( pCrvEL) || ! pCrvEL->IsValid()) + return false ; + if ( pCrvEL->IsPointOn( ptS, 300 * EPS_SMALL) && pCrvEL->IsPointOn( ptE, 300 * EPS_SMALL)) { + if ( ! pNewSfrInc->IsValid()) + pNewSfrInc.Set( pSfrInc->CloneChunk( i)) ; + else + if ( ! pNewSfrInc->Add( * pSfrInc->CloneChunk( i))) ; + } + } + if ( ! pNewSfrInc->IsValid()) + return false ; + pSfrInc.Set( Release( pNewSfrInc)) ; + } + } // controllo se la curva è un'isola bool bIsIsland = false ; @@ -9989,6 +10061,7 @@ Pocketing::AdjustOpenEdge( const ICurveComposite* pCrvCompo, const ICRVCOMPOPOVE double dUTrimS, dUTrimE ; pCrvNewBorder->GetParamAtPoint( ptStart, dUTrimS, 300 * EPS_SMALL) ; pCrvNewBorder->GetParamAtPoint( ptEnd, dUTrimE, 300 * EPS_SMALL) ; + // pulisco la curva originale pCrvBorder->Clear() ; if ( ! pCrvBorder->AddCurve( pCrvNewBorder->CopyParamRange( dUTrimS, dUTrimE)) || diff --git a/Pocketing.h b/Pocketing.h index d3d1f32..dbd90f4 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -94,10 +94,12 @@ class Pocketing : public Machining // Dijkstra bool ChooseBestBisectorPath( ICRVCOMPOPOVECTOR& vCrvCompo, const Point3d& ptS, const Point3d& ptE, ICurveComposite* pCrvPath) ; + bool GetSpecialElevation( const ISurfFlatRegion* pSfr, const ICurveLine* pLine, const bool bInVsOut, + double& dElev) ; bool SliceVolume( const ISurfTriMesh* pStmVol, const ISurfTriMesh* pStm_Part, ISURFFRPOVECTOR& vSrfSliced, - std::vector& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec, - VCT3DVECTOR& vVtTrasl, int& nStep, const Vector3d vtTool, + ISURFFRPOVECTOR& vSfrLimit, std::vector& vCrvOEWithFlags, + BOOLVECTOR& vbChangedPrec, VCT3DVECTOR& vVtTrasl, int& nStep, const Vector3d vtTool, const double dElev, const double dDepth, const double dStep) ; bool CalcExtraSteps( const ISurfTriMesh* pStmVol, VCT3DVECTOR& vVtTrasl, int& nStep, const double dElev, const double dDepth, const double dStep, INTVECTOR& vIndExtraSteps, @@ -169,7 +171,7 @@ class Pocketing : public Machining VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; bool AddSpiralIn( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, - VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, + VCT3DVECTOR& vVtTrasl, ISURFFRPOVECTOR& vSrfLimit, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, double dMaxElev, double dOkStep, bool bSplitArcs) ; bool AddSpiralOut( ISURFFRPOVECTOR& vSfr, const std::vector& vCrvOrig, BOOLVECTOR& vbChangedPrec, VCT3DVECTOR& vVtTrasl, const Vector3d& vtTool, const Vector3d& vtExtr, @@ -264,7 +266,7 @@ class Pocketing : public Machining 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 ISurfFlatRegion* pSfr, - ICurveComposite* pCrvStepLink) ; + const ISurfFlatRegion* pSfrLimit, ICurveComposite* pCrvStepLink) ; double GetRadiusForStartEndElevation( void) const ; // ===================================================================