diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 8679ca2..6ed2dd2 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -2155,8 +2155,9 @@ SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, cons //---------------------------------------------------------------------------- bool -SurfFinishing::GetZConstFacesInsideSfr( const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr, - const Vector3d& vtTool, set& setZAmbiguos) +SurfFinishing::GetZConstFacesInsideSfrParallelToTool( const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, + const ISurfFlatRegion* pSfr, const Vector3d& vtTool, + set& setZAmbiguos) { // controllo dei parametri setZAmbiguos.clear() ; @@ -2172,12 +2173,6 @@ SurfFinishing::GetZConstFacesInsideSfr( const SURFLOCALVECTOR& vSrfLoc, const Fr PtrOwner pSfrLoc( CloneSurfFlatRegion( pSfr)) ; if ( IsNull( pSfrLoc) || ! pSfrLoc->IsValid() || ! pSfrLoc->ToLoc( frSfr)) return false ; - // recupero le curve della regione - ICRVCOMPOPOVECTOR vCrvSfrLoc ; - for ( int nC = 0 ; nC < pSfrLoc->GetChunkCount() ; ++ nC) { - for ( int nL = 0 ; nL < pSfrLoc->GetLoopCount( nC) ; ++ nL) - vCrvSfrLoc.emplace_back( ConvertCurveToComposite( pSfrLoc->GetLoop( nC, nL))) ; - } // scorro le superfici trimesh selezionate for ( int nS = 0 ; nS < int( vSrfLoc.size()) ; ++ nS) { @@ -2196,37 +2191,35 @@ SurfFinishing::GetZConstFacesInsideSfr( const SURFLOCALVECTOR& vSrfLoc, const Fr // recupero i contorni della faccia POLYLINEVECTOR vPL ; if ( pStm->GetFacetLoops( nF, vPL)) { + // recupero la superficie piana dalle curve + SurfFlatRegionByContours SfrByC ; for ( int nPL = 0 ; nPL < int( vPL.size()) ; ++ nPL) { - // recupero il bordo della PolyLine PtrOwner pCrvCompo( CreateCurveComposite()) ; if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyLine( vPL[nPL])) return false ; - // se curva trascurabile, passo alla successiva - double dMaxOffs ; - if ( ! CalcCurveLimitOffset( *pCrvCompo, dMaxOffs)) - return false ; - if ( dMaxOffs < 1.5 * m_TParams.m_dTDiam) - continue ; // porto la curva nel riferimento globale pCrvCompo->ToGlob( frSurf) ; // porto la curva nel riferimento della pSfr (per la classificazione) pCrvCompo->ToLoc( frSfr) ; - // translo la curva a contatto con la pSfr - Point3d ptS ; vPL[nPL].GetFirstPoint( ptS) ; - pCrvCompo->Translate( ( - ptS.z) * Z_AX) ; - // controllo l'intersezione - bool bInters = false ; - for ( int i = 0 ; i < int( vCrvSfrLoc.size()) && ! bInters ; ++ i) { - IntersCurveCurve ICC( *vCrvSfrLoc[i], *pCrvCompo) ; - bInters = ( ICC.GetIntersCount() > 0) ; - } - if ( bInters) { - // porto il punto nel riferimento della superficie - ptCenter.ToGlob( frSurf) ; - ptCenter.ToLoc( frSfr) ; - // inserisco la Z del piano locale nell'insieme - setZAmbiguos.insert( ptCenter.z) ; - } + // aggiungo la curva alla FlatRegion + SfrByC.AddCurve( Release( pCrvCompo)) ; + } + // recupero la superficie + PtrOwner pSfrFace( SfrByC.GetSurf()) ; + if ( IsNull( pSfrFace) || ! pSfrFace->IsValid()) { + // in questo caso potrei avere goemtrie complesse per le facce della pStm + // inserisco la Z del piano locale nell'insieme + setZAmbiguos.insert( ptCenter.z) ; + continue ; + } + // se esiste intersezione tra pSfrFace e pSfr allora salvo la Z locale + pSfrFace->Intersect( *pSfrLoc) ; + if ( ! IsNull( pSfrFace) && pSfrFace->IsValid()) { + // porto il punto nel riferimento della superficie + ptCenter.ToGlob( frSurf) ; + ptCenter.ToLoc( frSfr) ; + // inserisco la Z del piano locale nell'insieme + setZAmbiguos.insert( ptCenter.z) ; } } } @@ -2288,9 +2281,12 @@ SurfFinishing::CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SU if ( IsNull( pSfrZAmb) || ! pSfrZAmb->IsValid() || ! pSfrZAmb->Offset( m_TParams.m_dDiam / 2. + abs( m_Params.m_dOverlap), ICurve::OFF_FILLET)) return false ; - if ( ! GetZConstFacesInsideSfr( vSrfLoc, frSurf, pSfrZAmb, vtTool, setZAmbiguos)) + if ( ! GetZConstFacesInsideSfrParallelToTool( vSrfLoc, frSurf, pSfrZAmb, vtTool, setZAmbiguos)) return false ; + // aggiorno la ProgressBar al 40% + ExeProcessEvents( 40, 0) ; + // calcolo la silhouette sui diversi piani for ( int nPlane = 1 ; nPlane * m_Params.m_dSideStep < dDepth + EPS_SMALL ; ++ nPlane) { // riservo lo spazio nel vettore delle curve @@ -2380,6 +2376,9 @@ SurfFinishing::CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SU if ( m_Params.m_bInvert) vCrvCompo.back()[i]->Invert() ; } + + // aggiorno la ProgressBar + ExeProcessEvents( 40 + ( 40 / ( dDepth / max( 0.1, m_Params.m_dSideStep)) * ( nPlane - 1)), 0) ; } // controllo la validità di tutte le curve trovate @@ -2513,7 +2512,7 @@ SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECT } } } - // se non ho trovato nessuna colonna valida (potrei controllare anche la distanza...) + // se non ho trovato nessuna colonna valida if ( nNextCol_path == -1) { nCurrRow = 0 ; // azzero il contatore delle righe break ; // interrompo ciclo sulle righe successive di ricerca @@ -2523,6 +2522,12 @@ SurfFinishing::CreateZConstPaths( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECT // definisco un tratto lineare che collega gli estremi Point3d ptStartLink = ptCurrEnd ; Point3d ptEndLink ; vCrvCompo[nNextRow][nNextCol_path]->GetStartPoint( ptEndLink) ; + // se i punti sono distanti, allora non considero valido il collegamento + if ( SqDist( ptStartLink, ptEndLink) > m_TParams.m_dDiam * 2) { + nCurrRow = 0 ; // azzero il contatore delle righe + break ; // interrompo ciclo sulle righe successive di ricerca + } + PtrOwner pLineLink( CreateCurveLine()) ; if ( IsNull( pLineLink) || ! pLineLink->Set( ptStartLink, ptEndLink) || ! pLineLink->IsValid()) @@ -2698,7 +2703,7 @@ SurfFinishing::CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d Vector3d vtMoveL = vtAxL ; // traslo della lunghezza utensile diminuita dell'affondamento PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; - // eseguo il test del percorso + // eseguo il test del percorso ( CONTROLLARE PROGRESS BAR DENTRO QUESTA FUNZIONE) if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox)) return false ; // contro-traslo della lunghezza utensile @@ -2736,6 +2741,10 @@ SurfFinishing::AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf // controllo che la regione sia definita correttamente if ( pSfr == nullptr || ! pSfr->IsValid()) return false ; + + // aggiorno la ProgressBar del 5% per simulare l'inizio della funzione + ExeProcessEvents( 5, 0) ; + // aggiusto la regione a seconda dei parametri PtrOwner pSfrClass( pSfr->CreateOffsetSurf( - m_TParams.m_dDiam / 2. + m_Params.m_dOverlap, ICurve::OFF_FILLET)) ; if ( IsNull( pSfrClass) || ! pSfrClass->IsValid()) @@ -2746,6 +2755,9 @@ SurfFinishing::AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf if ( IsNull( pCavParSilh)) return false ; + // aggiorno la ProgressBar al 40% per simulare l'inizio della funzione + ExeProcessEvents( 30, 0) ; + // recupero le curve singole definite dal bordo della Silhouette vector vCrvCompo ; if ( ! CalcZConstSilCrv( pCavParSilh, vSrfLoc, frSurf, pSfrClass, vtTool, dDepth, vCrvCompo)) { @@ -2768,7 +2780,8 @@ SurfFinishing::AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf // se non ho percorsi, errore if ( vCrvPath.empty()) return false ; - + ExeProcessEvents( 90, 0) ; + // recupero distanze di sicurezza double dSafeZ = GetSafeZ() ; // lunghezza di approccio/retrazione @@ -2925,6 +2938,7 @@ SurfFinishing::AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrf } } + ExeProcessEvents( 100, 0) ; return true ; } @@ -2989,24 +3003,6 @@ SurfFinishing::ApproxSilhouetteClosedPLForOptimal( PolyLine& PL, double dSampleT while ( PL.GetNextPoint( myPt)) vPts.emplace_back( myPt) ; - /*ICurveComposite* pCrvOrig = CreateCurveComposite() ; - for ( int i = 0 ; i < int( vPts.size()) ; ++ i) { - if ( i == 0) - pCrvOrig->AddPoint( vPts[i]) ; - else - pCrvOrig->AddLine( vPts[i]) ; - IGeoPoint3d* pt = CreateGeoPoint3d() ; - pt->Set( vPts[i]) ; - int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pt->Clone()) ; - m_pGeomDB->SetMaterial( a, WHITE) ; - } - pCrvOrig->Close() ; - int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrvOrig->Clone()) ; - m_pGeomDB->SetMaterial( a, GREEN) ; - LOG_ERROR( GetEMkLogger(), ("Samp tol -> " + to_string( dSampleTol)).c_str()) ; - LOG_ERROR( GetEMkLogger(), ("Lin tol ( 2*dMaxRad) -> " + to_string( dMaxLinTol)).c_str()) ; - LOG_ERROR( GetEMkLogger(), ("Ang tol -> " + to_string( dAngTol)).c_str()) ;*/ - // dichiaro i versori tangenti consecutivi per il percorso della PolyLinea Vector3d vtTanPrev, vtTan, vtTanAfter ; // recupero il cosendo della tolleranza angolare @@ -3032,10 +3028,6 @@ SurfFinishing::ApproxSilhouetteClosedPLForOptimal( PolyLine& PL, double dSampleT continue ; // se uno dei due sotto la tolleranza, analizzo segmento successivo // se Spike individuato, modifico il punto corrente con il punto medio del segmento attuale vPts[i] = Media( vPts[i], vPts[i-1]) ; - /*IGeoPoint3d* pt = CreateGeoPoint3d() ; - pt->Set( vPts[i]) ; - int a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pt->Clone()) ; - m_pGeomDB->SetMaterial( a, YELLOW) ;*/ // il punto precedente diventa uguale all' i-2-esimo vPts[i-1] = vPts[i-2] ; } @@ -3062,8 +3054,6 @@ SurfFinishing::ApproxSilhouetteClosedPLForOptimal( PolyLine& PL, double dSampleT // recupero la curva composita dalla polyLine if ( ! pCompoPL->FromPolyLine( PL) || ! pCompoPL->IsValid()) return false ; - /*int _b = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompoPL->Clone()) ; - m_pGeomDB->SetMaterial( _b, ORANGE) ;*/ // approssimo con archi PolyArc PA ; @@ -3080,8 +3070,6 @@ SurfFinishing::ApproxSilhouetteClosedPLForOptimal( PolyLine& PL, double dSampleT pTempCrv->FromPolyArc( PA) && pTempCrv->RemoveSmallDefects( dMaxLinTol, ANG_TOL_STD_DEG) && pTempCrv->MergeCurves( dMaxLinTol, ANG_TOL_STD_DEG)) { - /*int _a = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pTempCrv->Clone()) ; - m_pGeomDB->SetMaterial( _a, GREEN) ;*/ pCompoPL->CopyFrom( pTempCrv) ; } } @@ -3129,13 +3117,13 @@ SurfFinishing::GetSfrBySilhouette( ICAvParSilhouettesSurfTm* pCavParSilh, double bool SurfFinishing::SplitStmTrianglesForSpiralAndZConst( const ISurfTriMesh* pStm, const Frame3d& frSurf, const Vector3d& vtTool, double dClippingAngle, double dTolerAngle, - StmFromTriangleSoup& TriaSoup, double& dMaxFrontTriaRad) + StmFromTriangleSoup& TriaSoup, double& dMaxFrontTriaRad) const { - //Funzione per ciclare i triangoli di una TriMesh (*pStm) partendo da nT_start e terminando a nT_end - //I triangoli che formano un angolo in valore assoluto con vtTool, maggiore di dClippingAngle - //vengono inseriti nella zuppa - //dMaxFrontTriaRad è il raggio massimo dei triangoli con normale che si discosta da vtTool per - //meno di dTolerAngle (triangoli frontalieri) + // Funzione per ciclare i triangoli di una TriMesh (*pStm) partendo da nT_start e terminando a nT_end + // I triangoli che formano un angolo in valore assoluto con vtTool, maggiore di dClippingAngle + // vengono inseriti nella zuppa TriaSoup + // dMaxFrontTriaRad è il raggio massimo dei triangoli con normale che si discosta da vtTool per + // meno di dTolerAngle (triangoli frontalieri) // controllo della superficie if ( pStm == nullptr || ! pStm->IsValid()) @@ -3151,16 +3139,17 @@ SurfFinishing::SplitStmTrianglesForSpiralAndZConst( const ISurfTriMesh* pStm, co double dCosLimSup = cos( ( dClippingAngle - dTolerAngle) * DEGTORAD) ; double dCosLimInf = cos( max( 0., ( dClippingAngle + dTolerAngle)) * DEGTORAD) ; double dAbsCosPerpTol = dTolerAngle * DEGTORAD ; // x->PI/2, cos(x) ~ -x + PI/2 + int nTria = pStm->GetTriangleCount() ; // scorro i triangoli della superficie - for ( int nT = 0 ; nT < pStm->GetTriangleCount() ; ++ nT) { + for ( int nT = 0 ; nT < nTria ; ++ nT) { // recupero il triangolo corrente (controllo la sua validità) Triangle3d Tria ; pStm->GetTriangle( nT, Tria) ; if ( ! Tria.IsValid()) continue ; // recupero la normale del triangolo Vector3d vtN_tria = Tria.GetN() ; - // se i due versori sono quasi paralleli, passo al triangolo successivo + // se i due versori sono quasi paralleli il triangolo vengono saltati // ( se faccia piana equiversa a vtToolLoc allora è in Spiral, se opposta non la considero) if ( AreSameOrOppositeVectorEpsilon( vtN_tria, vtToolLoc, 50 * EPS_SMALL)) continue ; @@ -3211,11 +3200,11 @@ SurfFinishing::SplitStmInTwoSilSfrByClippingAngle( const SURFLOCALVECTOR& vSrfLo return false ; // parametri e costanti per il calcolo della regione - double dMaxRad = 100 * EPS_SMALL ; // raggio massimo della sfera che contiene i triangoli frontalieri - const double OFFS_TRIA_ANG_TOL = 2. ; // tolleranza di ricerca dei triangoli frontalieri - const double OFFS_CORR = 0. ; // offset correttivo regione piana ZConst + double dMaxRad = 100. * EPS_SMALL ; // raggio massimo della sfera che contiene i triangoli frontalieri + const double OFFS_TRIA_ANG_TOL = 2. ; // tolleranza di ricerca dei triangoli frontalieri + const double OFFS_CORR = 0. ; // offset correttivo regione piana ZConst - // creazione della zuppa di triangoli per la Zconst + // creazione della zuppa di triangoli per la Zconst e zuppa per triangoli perpendicolari a vtTool StmFromTriangleSoup StmSoup ; StmSoup.Start() ; // scorro il vettore delle regioni piane @@ -3235,7 +3224,7 @@ SurfFinishing::SplitStmInTwoSilSfrByClippingAngle( const SURFLOCALVECTOR& vSrfLo } StmSoup.End() ; - // definisco vettori superfici locali ZConst + // definisco vettori superfici locali ZConst e superficiTM perpendicolari a vtTool CISURFTMPVECTOR vStmLocZConst ; // recupero le superfici trimesh PtrOwner pStmCurr( StmSoup.GetSurf()) ; @@ -3313,6 +3302,8 @@ SurfFinishing::SplitStmInTwoSilSfrByClippingAngle( const SURFLOCALVECTOR& vSrfLo } } + // aggiorno la ProgressBar al 40% + ExeProcessEvents( 40, 0) ; return true ; } @@ -3427,13 +3418,13 @@ bool SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr, const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) { - // !!! per ora (Test) !!! - return true ; - // controllo che la regione sia definita correttamente if ( pSfr == nullptr || ! pSfr->IsValid()) return false ; + // aggiorno la ProgressBar del 5% per simulare l'inizio della funzione + ExeProcessEvents( 5, 0) ; + // recupero distanze di sicurezza double dSafeZ = GetSafeZ() ; // lunghezza di approccio/retrazione @@ -3453,79 +3444,88 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr // ----------------------- Lavorazione Spiral/ZigZag ------------------------------- if ( ! IsNull( pSfrSpiral) && pSfrSpiral->IsValid()) { - // aggiusto la regione a seconda dei parametri (il centro utensile deve stare sul bordo) - PtrOwner pSfrToWork( pSfrSpiral->CreateOffsetSurf( m_TParams.m_dDiam / 2. - m_Params.m_dOverlap, ICurve::OFF_FILLET)) ; - if ( IsNull( pSfrToWork) || ! pSfrToWork->IsValid()) - return false ; // mi assicuro di non uscire dalla superficie originale - pSfrToWork->Intersect( *pSfr) ; - // assegno tutte proprietà di lato chiuso - for ( int nC = 0 ; nC < pSfrToWork->GetChunkCount() ; ++ nC) { - for ( int nL = 0 ; nL < pSfrToWork->GetLoopCount( nC) ; ++ nL) { - for ( int nU = 0 ; nU < pSfrToWork->GetLoopCurveCount( nC, nL) ; ++ nU) - pSfrToWork->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ; - } - } - // lavorazione Spiral/ZigZag - ICRVCOMPOPOVECTOR vpCrvs ; - if ( ! CalcPocketing( pSfrToWork, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, - POCKET_SPIRALIN, false, false, true, false, P_INVALID, nullptr, vpCrvs)) { - m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; - return false ; - } + pSfrSpiral->Intersect( *pSfr) ; // determino il riferimento di base della svuotatura Frame3d frPocket ; Point3d ptCen ; pSfr->GetCentroid( ptCen) ; frPocket.Set( ptCen, vtTool) ; - // ciclo sui percorsi ricavati risultanti - double dProgCoeff = 1. / max( int( vpCrvs.size()), 1) ; - for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { - // definisco un nuovo percorso (in locale) - vPaths.resize( vPaths.size() + 1) ; - vPaths.back().pCrvPath.Set( Release( vpCrvs[k])) ; - vPaths.back().pCrvPath->ToLoc( frPocket) ; - vPaths.back().nType = SURFFIN_SUB_SPIRALIN ; - // li correggo per non interferire con le superfici - if ( pCAvTlStm != nullptr) { - // approssimo la curva con una polilinea - PolyLine PL ; - if ( ! vPaths.back().pCrvPath->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) - return false ; - // eventuale aggiunta di punti per garantire max distanza - const double MIN_DIST = 1. ; - const double MAX_DIST = 50. ; - double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; - if ( ! PL.AdjustForMaxSegmentLen( dDist)) - return false ; - // porto nel riferimento delle superfici - PL.LocToLoc( frPocket, frSurf) ; - // porto i dati geometrici in locale alle superfici - Vector3d vtAxL = vtTool ; - vtAxL.ToLoc( frSurf) ; - Vector3d vtMoveL = vtAxL ; - // traslo della lunghezza utensile diminuita dell'affondamento - PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; - // eseguo CAv - if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( k + 1) * dProgCoeff)) - return false ; - // contro-traslo della lunghezza utensile - PL.Translate( - vtAxL * m_TParams.m_dLen) ; - // riporto la polilinea nel riferimento della curva - PL.LocToLoc( frSurf, frPocket) ; - // elimino i punti allineati - PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; - // creo una curva composita a partire dalla polilinea - PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; - if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) - return false ; - // sostituisco la vecchia curva con la nuova - vPaths.back().pCrvPath.Set( pCompo) ; + // lavoro ogni singolo Chunk singolarmente ( non estendo lati aperti per eveitare merge con gli stessi Chunks) + for ( int nC = 0 ; nC < pSfrSpiral->GetChunkCount() ; ++ nC) { + // recupero il Chunk come regione piana + PtrOwner pSfrToWork( pSfrSpiral->CloneChunk( nC)) ; + if ( IsNull( pSfrToWork) || ! pSfrToWork->IsValid()) + return false ; + // Offset + if ( ! pSfrToWork->Offset( dPockRadOffs, ICurve::OFF_FILLET)) + return false ; + // imposto i lati chiusi + for ( int nCC = 0 ; nCC < pSfrToWork->GetChunkCount() ; ++ nCC) { + for ( int nL = 0 ; nL < pSfrToWork->GetLoopCount( nCC) ; ++ nL) { + for ( int nU = 0 ; nU < pSfrToWork->GetLoopCurveCount( nCC, nL) ; ++ nU) + pSfrToWork->SetCurveTempProp( nCC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ; + } + } + // lavorazione Spiral/ZigZag + ICRVCOMPOPOVECTOR vpCrvs ; + if ( ! CalcPocketing( pSfrToWork, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, + POCKET_SPIRALIN, false, false, true, false, P_INVALID, nullptr, vpCrvs)) { + m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; + return false ; + } + // ciclo sui percorsi ricavati risultanti + double dProgCoeff = 1. / max( int( vpCrvs.size()), 1) ; + for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { + // definisco un nuovo percorso (in locale) + vPaths.resize( vPaths.size() + 1) ; + vPaths.back().pCrvPath.Set( Release( vpCrvs[k])) ; + vPaths.back().pCrvPath->ToLoc( frPocket) ; + vPaths.back().nType = SURFFIN_SUB_SPIRALIN ; + // li correggo per non interferire con le superfici + if ( pCAvTlStm != nullptr) { + // approssimo la curva con una polilinea + PolyLine PL ; + if ( ! vPaths.back().pCrvPath->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) + return false ; + // eventuale aggiunta di punti per garantire max distanza + const double MIN_DIST = 1. ; + const double MAX_DIST = 50. ; + double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; + if ( ! PL.AdjustForMaxSegmentLen( dDist)) + return false ; + // porto nel riferimento delle superfici + PL.LocToLoc( frPocket, frSurf) ; + // porto i dati geometrici in locale alle superfici + Vector3d vtAxL = vtTool ; + vtAxL.ToLoc( frSurf) ; + Vector3d vtMoveL = vtAxL ; + // traslo della lunghezza utensile diminuita dell'affondamento + PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; + // eseguo CAv + if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox, ( k + 1) * dProgCoeff)) + return false ; + // contro-traslo della lunghezza utensile + PL.Translate( - vtAxL * m_TParams.m_dLen) ; + // riporto la polilinea nel riferimento della curva + PL.LocToLoc( frSurf, frPocket) ; + // elimino i punti allineati + PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; + // creo una curva composita a partire dalla polilinea + PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) + return false ; + // sostituisco la vecchia curva con la nuova + vPaths.back().pCrvPath.Set( pCompo) ; + } } } - // porto tutti i percorsi nel frame globale + // porto tutti i percorsi nel frame globale for ( int i = 0 ; i < int( vPaths.size()) ; ++ i) vPaths[i].pCrvPath->ToGlob( frPocket) ; } + + // aggiorno la ProgressBar al 60% + ExeProcessEvents( 5, 0) ; #if ENABLE_OPTIMAL_DEBUG // disegno i percorsi per controllo int ___a = int( vPaths.size()) ; @@ -3537,46 +3537,53 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr // ----------------------- Lavorazione Zconst ------------------------------- if ( ! IsNull( pSfrZConst) && pSfrZConst->IsValid()) { - // aggiusto la regione a seconda dei parametri (il centro utensile deve stare sul bordo) - PtrOwner pSfrToWork( pSfrZConst->CreateOffsetSurf( 0., ICurve::OFF_FILLET)) ; - if ( IsNull( pSfrToWork) || ! pSfrToWork->IsValid()) - return false ; // mi assicuro di non uscire dalla superficie originale - pSfrToWork->Intersect( *pSfr) ; - // assegno tutte proprietà di lato chiuso - for ( int nC = 0 ; nC < pSfrToWork->GetChunkCount() ; ++ nC) { - for ( int nL = 0 ; nL < pSfrToWork->GetLoopCount( nC) ; ++ nL) { - for ( int nU = 0 ; nU < pSfrToWork->GetLoopCurveCount( nC, nL) ; ++ nU) - pSfrToWork->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ; + pSfrZConst->Offset( m_Params.m_dSideStep, ICurve::OFF_FILLET) ; + pSfrZConst->Intersect( *pSfr) ; + // lavoro ogni singolo Chunk singolarmente ( non estendo lati aperti per eveitare merge con gli stessi Chunks) + for ( int nC = 0 ; nC < pSfrZConst->GetChunkCount() ; ++ nC) { + // recupero il Chunk come regione piana + PtrOwner pSfrToWork( pSfrZConst->CloneChunk( nC)) ; + if ( IsNull( pSfrToWork) || ! pSfrToWork->IsValid()) + return false ; + // imposto i lati chiusi + for ( int nCC = 0 ; nCC < pSfrToWork->GetChunkCount() ; ++ nCC) { + for ( int nL = 0 ; nL < pSfrToWork->GetLoopCount( nCC) ; ++ nL) { + for ( int nU = 0 ; nU < pSfrToWork->GetLoopCurveCount( nCC, nL) ; ++ nU) + pSfrToWork->SetCurveTempProp( nC, nL, nU, 0, TEMP_PROP_CLOSE_EDGE) ; + } } - } - // inizializzo la classe di calcolo delle silhouette nei piani come sopra - PtrOwner pCavParSilh( GetParSilhouettesForZConst( vSrfLoc, frSurf, pSfrToWork)) ; - if ( IsNull( pCavParSilh)) - return false ; - // recupero le curve singole definite dal bordo della Silhouette - vector vCrvCompo ; - if ( ! CalcZConstSilCrv( pCavParSilh, vSrfLoc, frSurf, pSfrToWork, vtTool, dDepth, vCrvCompo)) { - m_pMchMgr->SetLastError( 3126, "Error in SurfFinishing : Computing ZConst Curves failed") ; - return false ; - } - // se ho delle curve, allora unisco i percorsi trovati - if ( ! vCrvCompo.empty()) { - // collego tra loro le curve trovate - ICRVCOMPOPOVECTOR vCrv ; - if ( ! CreateZConstPaths( pCAvTlStm, vSrfLoc, frSurf, vCrvCompo, vtTool, pSfrToWork, dDepth, vCrv)) { - m_pMchMgr->SetLastError( 3127, "Error in SurfFinishing : Computing ZConst Paths failed") ; + // inizializzo la classe di calcolo delle silhouette nei piani come sopra + PtrOwner pCavParSilh( GetParSilhouettesForZConst( vSrfLoc, frSurf, pSfrToWork)) ; + if ( IsNull( pCavParSilh)) + return false ; + // recupero le curve singole definite dal bordo della Silhouette + vector vCrvCompo ; + if ( ! CalcZConstSilCrv( pCavParSilh, vSrfLoc, frSurf, pSfrToWork, vtTool, dDepth, vCrvCompo)) { + m_pMchMgr->SetLastError( 3126, "Error in SurfFinishing : Computing ZConst Curves failed") ; return false ; } - // aggiungo i percorsi trovati - for ( int i = 0 ; i < int( vCrv.size()) ; ++ i) { - vPaths.resize( vPaths.size() + 1) ; - vPaths.back().pCrvPath.Set( Release( vCrv[i])) ; - vPaths.back().nType = SURFFIN_SUB_ZIGZAG ; + // se ho delle curve, allora unisco i percorsi trovati + if ( ! vCrvCompo.empty()) { + // collego tra loro le curve trovate + ICRVCOMPOPOVECTOR vCrv ; + if ( ! CreateZConstPaths( pCAvTlStm, vSrfLoc, frSurf, vCrvCompo, vtTool, pSfrToWork, dDepth, vCrv)) { + m_pMchMgr->SetLastError( 3127, "Error in SurfFinishing : Computing ZConst Paths failed") ; + return false ; + } + // aggiungo i percorsi trovati + for ( int i = 0 ; i < int( vCrv.size()) ; ++ i) { + vPaths.resize( vPaths.size() + 1) ; + vPaths.back().pCrvPath.Set( Release( vCrv[i])) ; + vPaths.back().nType = SURFFIN_SUB_ZIGZAG ; + } } } } + // aggiorno la ProgressBar all' 80% + ExeProcessEvents( 80, 0) ; + #if ENABLE_OPTIMAL_DEBUG // disegno i percorsi per controllo for ( int i = ___a ; i < int( vPaths.size()) ; ++ i) { @@ -3588,11 +3595,18 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr // ordino i percorsi in base alla Zlocale if ( ! OrderOptimalPathsByZLoc( pSfr, vPaths)) return false ; + // aggiorno la ProgressBar all' 80% + ExeProcessEvents( 90, 0) ; + // aggiusto la regione a seconda dei parametri PtrOwner pSfrClass( pSfr->CreateOffsetSurf( - m_TParams.m_dDiam / 2. + m_Params.m_dOverlap, ICurve::OFF_FILLET)) ; if ( IsNull( pSfrClass) || ! pSfrClass->IsValid()) return false ; - + // piano definito dalla pSfr + Point3d ptCenter ; pSfr->GetCentroid( ptCenter) ; + Plane3d plSfr ; + if ( ! plSfr.Set( ptCenter, vtTool)) + return false ; // inserisco i percorsi bool bStart = true ; // ciclo sulle curve risultanti @@ -3642,10 +3656,15 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr // eventuale correzione inizio attacco per evitare interferenze if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptStart, ptP1, vtTool, ptP1)) return false ; - // se ZConst, controllo che tale punto sia al di fuori della regione piana + // controllo che tale punto sia al di fuori della regione piana if ( vPaths[k].nType == SURFFIN_SUB_Z_CONST) { bool bIsInside = false ; - if ( IsPointInsideSurfFr( ptP1 + vtTool * ( m_Params.m_dSideStep * nStartPlane), pSfrClass, EPS_SMALL, bIsInside)) + if ( IsPointInsideSurfFr( ptP1 + vtTool * ( m_Params.m_dSideStep * nStartPlane), pSfrClass, EPS_SMALL, bIsInside) && ! bIsInside) + ptP1 = ptStart ; + } + else { + bool bIsInside = false ; + if ( IsPointInsideSurfFr( ProjectPointOnPlane( ptP1, plSfr), pSfrClass, EPS_SMALL, bIsInside) && ! bIsInside) ptP1 = ptStart ; } // determino elevazione su inizio attacco @@ -3754,6 +3773,8 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr } } + // aggiorno la ProgressBar all' 100% + ExeProcessEvents( 100, 0) ; return true ; } diff --git a/SurfFinishing.h b/SurfFinishing.h index 5c4c326..838dd67 100644 --- a/SurfFinishing.h +++ b/SurfFinishing.h @@ -106,16 +106,14 @@ class SurfFinishing : public Machining bool OrderOptimalPathsByZLoc( const ISurfFlatRegion* pSfr, VECTORPATHS& vCrvPaths) ; bool SplitStmTrianglesForSpiralAndZConst( const ISurfTriMesh* pStm, const Frame3d& frSurf, const Vector3d& vtTool, double dClippingAngle, double dTolerAngle, - StmFromTriangleSoup& TriaSoup, double& dMaxFrontTriaRad) ; + StmFromTriangleSoup& TriaSoup, double& dMaxFrontTriaRad) const ; bool GetSfrBySilhouette( ICAvParSilhouettesSurfTm* pCavParSilh, double dDepth, double dSilTolSamp, double dSilTolLin, double dSilTolAng, ISurfFlatRegion* pSfrSil) ; bool ApproxSilhouetteClosedPLForOptimal( PolyLine& PL, double dSampleTol, double dMaxLinTol, double dAngTol, double dLinFeaTol, ICurveComposite* pCompoPL) ; bool SplitStmInTwoSilSfrByClippingAngle( const SURFLOCALVECTOR&, const Frame3d& frSurf, const ISurfFlatRegion* pSfrCnt, double dDepth, const Vector3d& vtTool, double dClippingAngle, ISurfFlatRegion* pSfrSpiral, ISurfFlatRegion* pSfrZConst) ; - bool GetZConstFacesInsideSfr( const SURFLOCALVECTOR& - - , const Frame3d& frSurf, const ISurfFlatRegion* pSfr, - const Vector3d& vtTool, std::set& setZAmbiguos) ; + bool GetZConstFacesInsideSfrParallelToTool( const SURFLOCALVECTOR&, const Frame3d& frSurf, const ISurfFlatRegion* pSfr, + const Vector3d& vtTool, std::set& setZAmbiguos) ; ICAvParSilhouettesSurfTm* GetParSilhouettesForZConst( const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr) const ; bool CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr,