EgtMachKernel :

- utilizzo della funzione limite per LeadIn/Out.
This commit is contained in:
Riccardo Elitropi
2024-01-11 17:57:23 +01:00
parent 8ae1d4cdc2
commit ac8feb7a17
2 changed files with 196 additions and 121 deletions
+190 -117
View File
@@ -2296,9 +2296,11 @@ Pocketing::ProcessPath( int nPathId, int nPvId, int nClId)
vector<ICRVCOMPOPOVECTOR> 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<ISurfFlatRegion> 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<ICurveComposite> 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<ISurfFlatRegion> 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<ICurveComposite> 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<ICRVCOMPOPOVECTOR>& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec,
ISURFFRPOVECTOR& vSfrLimit, std::vector<ICRVCOMPOPOVECTOR>& 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<ICRVCOMPOPOVECTOR
//----------------------------------------------------------------------------
bool
Pocketing::AddSpiralIn( ISURFFRPOVECTOR& vSfr, const vector<ICRVCOMPOPOVECTOR>& 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<ICRVCOMPOPOVECTOR>&
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<ICRVCOMPOPOVECTOR>&
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<ICRVCOMPOPOVECTOR>&
//----------------------------------------------------------------------------
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<ISurfFlatRegion> 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<ICurveLine> 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<ISurfFlatRegion> 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<ISurfFlatRegion> 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<ISurfFlatRegion> 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<ICurveComposite> 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<ICurveLine> pLineToStart( CreateCurveLine()) ;
if ( IsNull( pLineToStart) ||
! pLineToStart->Set( ORIG, ptS_path) ||
! pSfrSafe->GetCurveClassification( *pLineToStart, EPS_SMALL, ccClass_line))
PtrOwner<ICurveLine> 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<ICurveLine> pLineToEnd( CreateCurveLine()) ;
if ( IsNull( pLineToEnd) ||
! pLineToEnd->Set( ptEProj, ptE_path) ||
! pSfrSafe->GetCurveClassification( *pLineToEnd, EPS_SMALL, ccClass_line))
PtrOwner<ICurveLine> 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<ISurfFlatRegion> pSfrCurr( CloneSurfFlatRegion( pSfr)) ;
PtrOwner<ICurveLine> 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<ISurfFlatRegion> 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<ICurveComposite> 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)) ||
+6 -4
View File
@@ -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<ICRVCOMPOPOVECTOR>& vCrvOEWithFlags, BOOLVECTOR& vbChangedPrec,
VCT3DVECTOR& vVtTrasl, int& nStep, const Vector3d vtTool,
ISURFFRPOVECTOR& vSfrLimit, std::vector<ICRVCOMPOPOVECTOR>& 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<ICRVCOMPOPOVECTOR>& 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<ICRVCOMPOPOVECTOR>& 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 ;
// ===================================================================