EgtMachKernel :

- aggiunta finitura Optimal.
This commit is contained in:
Riccardo Elitropi
2025-01-20 11:40:13 +01:00
parent 7a864d9503
commit 4f2c322af8
2 changed files with 199 additions and 180 deletions
+196 -175
View File
@@ -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<double>& setZAmbiguos)
SurfFinishing::GetZConstFacesInsideSfrParallelToTool( const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf,
const ISurfFlatRegion* pSfr, const Vector3d& vtTool,
set<double>& setZAmbiguos)
{
// controllo dei parametri
setZAmbiguos.clear() ;
@@ -2172,12 +2173,6 @@ SurfFinishing::GetZConstFacesInsideSfr( const SURFLOCALVECTOR& vSrfLoc, const Fr
PtrOwner<ISurfFlatRegion> 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<ICurveComposite> 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<ISurfFlatRegion> 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<ICurveLine> 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<ISurfFlatRegion> 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<ICRVCOMPOPOVECTOR> 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<ISurfTriMesh> 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<ISurfFlatRegion> 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<ISurfFlatRegion> 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<ISurfFlatRegion> 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<ISurfFlatRegion> 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<ICAvParSilhouettesSurfTm> pCavParSilh( GetParSilhouettesForZConst( vSrfLoc, frSurf, pSfrToWork)) ;
if ( IsNull( pCavParSilh))
return false ;
// recupero le curve singole definite dal bordo della Silhouette
vector<ICRVCOMPOPOVECTOR> 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<ICAvParSilhouettesSurfTm> pCavParSilh( GetParSilhouettesForZConst( vSrfLoc, frSurf, pSfrToWork)) ;
if ( IsNull( pCavParSilh))
return false ;
// recupero le curve singole definite dal bordo della Silhouette
vector<ICRVCOMPOPOVECTOR> 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<ISurfFlatRegion> 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 ;
}
+3 -5
View File
@@ -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<double>& setZAmbiguos) ;
bool GetZConstFacesInsideSfrParallelToTool( const SURFLOCALVECTOR&, const Frame3d& frSurf, const ISurfFlatRegion* pSfr,
const Vector3d& vtTool, std::set<double>& 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,