EgtMachKernel 3.1e1 :

- In PocketingNT aggiunta gestione lavorazioni in Doppio in Parallelo.
This commit is contained in:
Riccardo Elitropi
2026-05-04 17:13:00 +02:00
parent f7251bf3bd
commit ac45a259b6
4 changed files with 390 additions and 58 deletions
-2
View File
@@ -3348,8 +3348,6 @@ Drilling::VerifyParallelDrilling( int nDouble, const Hole& hole)
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr)
return false ;
// verifico se la macchina presenta nel file .ini l'abilitazione per le forature in doppio in parallelo
string sMachIni = pMch->GetMachineDir() + "\\" + pMch->GetMachineName() + ".ini" ;
int nDrillingDouble = GetPrivateProfileInt( MACHININGS_SEC.c_str(), DRILLING_PARALLEL_KEY.c_str(), 0, sMachIni.c_str()) ;
if ( nDrillingDouble != 1)
BIN
View File
Binary file not shown.
+382 -53
View File
@@ -126,9 +126,11 @@ static double TOOL_RAD_PTSTART = 20. ;
#define DEBUG_START_POINT 0 // Debug per scelta del punto iniziale
#define DEBUG_PATH_CL 0 // Debug per valori memorizzati nel percorso del CL
#define DEBUG_ZIGZAG_LEADIN 0 // Debug per ZigZag LeadIn
#define DEBUG_DOUBLE_PARALLEL 0 // Debug per Pocketing in Doppio con Parallelo
#define DEBUG 0 // Debug
#if DEBUG_STM_TOPOLOGY || DEBUG_OPEN_EDGE_EXTENSION || DEBUG_OPEN_EDGE_IN_RAW || DEBUG_SFR_STEPS || DEBUG_SFR_RAW || DEBUG_SFR_GEO_EXT || \
DEBUG_GLIDE || DEBUG_SAFETY_LINK || DEBUG_FEED || DEBUG_START_POINT || DEBUG_PATH_CL || DEBUG_ZIGZAG_LEADIN || DEBUG
DEBUG_GLIDE || DEBUG_SAFETY_LINK || DEBUG_FEED || DEBUG_START_POINT || DEBUG_PATH_CL || DEBUG_ZIGZAG_LEADIN || DEBUG_DOUBLE_PARALLEL || \
DEBUG
#include "EgtDev/Include/EGkGeoPoint3d.h"
#include "EgtDev/Include/EGkGeoVector3d.h"
#include "EgtDev/Include/EGkFrame3d.h"
@@ -3942,28 +3944,57 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
// verifico se archi vanno approssimati con segmenti di retta
bool bSplitArcs = GetSplitArcs( vtExtr) ;
// determino numero e affondamento degli step
int nStep = max( 1, static_cast<int>( ceil( dElev / dOkStep))) ;
double dStep = dElev / nStep ;
// verifico se svuotatura in doppio con parte di essa da eseguire in parallelo
// determino dunque numero e affondamento degli step
int nStep = 0 ;
double dStep = - EPS_SMALL, dLastStep = - EPS_SMALL ;
DBLVECTOR vdSteps ;
int nDouble = GetDoubleType( m_Params.m_sUserNotes) ;
bool bDouble = ( nDouble != 0) ;
bool bUniformStep = true ;
if ( bDouble) {
// solo se lavorazione in doppio, recupero il LastStep se presente
dLastStep = GetDoubleLastStep() ;
if ( dLastStep > EPS_SMALL && abs( dLastStep - m_Params.m_dStep) > 10. * EPS_SMALL) {
double dStepPart = dElev - dLastStep ;
bUniformStep = ( dStepPart < EPS_SMALL) ; // se LastStep maggiore dell'elevazione, allora non lo considero
if ( bUniformStep) {
string sInfo = "Warning in PocketingNT : LastStep (" + ToString( dLastStep, 3) + ") bigger than"
"Elevation (" + ToString( dElev, 3) + ")" ;
m_pMchMgr->SetWarning( 2458, sInfo) ;
}
else {
nStep = max( 1, static_cast<int>( ceil( dStepPart / dOkStep))) ;
dStep = dStepPart / nStep ;
for ( int i = 1 ; i <= nStep ; ++ i)
vdSteps.push_back( i * dStep) ;
vdSteps.push_back( vdSteps.back() + dLastStep) ;
}
}
}
if ( bUniformStep) {
nStep = max( 1, static_cast<int>( ceil( dElev / dOkStep))) ;
dStep = dElev / nStep ;
for ( int i = 1 ; i <= nStep ; ++ i)
vdSteps.push_back( i * dStep) ;
}
// step per progressBar
int nProgressBarStep = 0 ;
// vettore per gli step
STEPINFOPOVECTOR vStepInfo ;
STEPINFOPOVECTOR vStepInfo ; vStepInfo.reserve( vdSteps.size()) ;
// regione esterna per Geometria di Selezione
ISURFFRPOVECTOR vSfrGeoExt ;
CalcGeoExtSurfFr( pSfr, vtTool, dDepth - dElev + nStep * dStep, ( pStmTrim == nullptr ? pStmRaw : pStmTrim), vGeoSel, vSfrGeoExt) ;
CalcGeoExtSurfFr( pSfr, vtTool, dDepth - dElev + vdSteps.back(), ( pStmTrim == nullptr ? pStmRaw : pStmTrim), vGeoSel, vSfrGeoExt) ;
for ( int j = 1 ; j <= nStep ; ++ j) {
for ( int j = 0 ; j < ssize( vdSteps) ; ++ j) {
// per i contatori non controllo se effettivamente svuoto una superficie o meno
++ nProgressBarStep ; // aggiorno step per progressBar
// porto la superficie allo step corrente
PtrOwner<ISurfFlatRegion> pSfrPock( CloneSurfFlatRegion( pSfr)) ;
if ( IsNull( pSfrPock) || ! pSfrPock->IsValid() ||
! pSfrPock->Translate( - vtTool * ( dDepth - dElev + j * dStep)))
! pSfrPock->Translate( - vtTool * ( dDepth - dElev + vdSteps[j])))
return false ;
// adatto la regione piana alla geometria del grezzo
@@ -4021,8 +4052,8 @@ PocketingNT::ProcessPath( int nPathId, int nPvId, int nClId)
#endif
// inserisco le informazioni dello step nel vettore
vStepInfo.resize( vStepInfo.size() + 1) ;
vStepInfo.back().dDepth = j * dStep ;
vStepInfo.back().dRelativeDepth = dStep ;
vStepInfo.back().dDepth = vdSteps[j] ;
vStepInfo.back().dRelativeDepth = ( j + 1 == ssize( vdSteps) && ! bUniformStep ? dLastStep : dStep) ;
vStepInfo.back().pSfrPock.Set( Release( pSfrPock)) ;
vStepInfo.back().pSfrLimit.Set( CreateSurfFlatRegion()) ;
if ( pSfrLimit->IsValid())
@@ -4530,7 +4561,7 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
// punto finale di riferimento per il percorso attuale ( serve per trovare il punto iniziale
// del percorso successivo). Parto analizzando la testa ( da sopra/da sotto)
Point3d ptStartRef = GetStartPointsByHead( vStepInfo) ;
// --- se punto invalido e raggio utensile grande se raggio utensile grande
// --- se punto invalido e raggio utensile grande
if ( ! ptStartRef.IsValid() && m_TParams.m_dDiam / 2. > TOOL_RAD_PTSTART - EPS_ZERO) {
// cerco l'ingresso in base alla geometria iniziale della tasca
ptStartRef = GetStartPointsFromSteps( vStepInfo, TEMP_PROP_OPEN_EDGE) ;
@@ -4589,11 +4620,11 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
if ( vCrvPaths.empty())
return false ;
// sistemo gli archi per massimo angolo al centro
for ( int j = 0 ; j < int( vCrvPaths.size()) ; ++ j)
for ( int j = 0 ; j < ssize( vCrvPaths) ; ++ j)
VerifyArcs( vCrvPaths[j]) ;
// inserisco i percorsi nel vettore dei Paths
vStepInfo[i].vPaths.resize( int( vCrvPaths.size())) ;
for ( int j = 0 ; j < int( vCrvPaths.size()) ; ++ j) {
vStepInfo[i].vPaths.resize( vCrvPaths.size()) ;
for ( int j = 0 ; j < ssize( vCrvPaths) ; ++ j) {
// controllo se il percorso ha un ingresso presso un lato aperto
vStepInfo[i].vPaths[j].bOutStart = ( vCrvPaths[j]->GetCurveCount() > 0 &&
vCrvPaths[j]->GetFirstCurve()->GetTempProp( 0) == TEMP_PROP_OUT_START) ;
@@ -4642,7 +4673,7 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
}
// definisco il nuovo punto di riferimento per il percorso successivo
// Se caso ottimizzato a spirale
if ( int( vStepInfo[i].vPaths.size()) == 1 && vStepInfo[i].vPaths[0].bOptCirle) {
if ( ssize( vStepInfo[i].vPaths) == 1 && vStepInfo[i].vPaths[0].bOptCirle) {
// Se entrata da fuori, ricomincio dall'esterno
if ( vStepInfo[i].vPaths[0].bOutStart)
vStepInfo[i].vPaths[0].pCrvPath->GetStartPoint( ptStartRef) ;
@@ -4658,16 +4689,14 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
else
vStepInfo[i].vPaths.front().pCrvPath->GetStartPoint( ptStartRef) ;
// aggiorno la progressBar
ExeProcessEvents( 50 + i * 50 / int( vStepInfo.size()), 0) ;
ExeProcessEvents( 50 + i * 50 / ssize( vStepInfo), 0) ;
}
// controllo se la svuotatura è riferita ad un foro chiuso
bool bHolePocketing = true ;
for ( int i = 0 ; i < int( vStepInfo.size()) && bHolePocketing ; ++ i) {
bHolePocketing = ( int( vStepInfo[i].vPaths.size()) == 1 &&
vStepInfo[i].vPaths[0].bOptCirle &&
! vStepInfo[i].vPaths[0].bOutStart &&
! vStepInfo[i].vPaths[0].bOutEnd) ;
for ( int i = 0 ; i < ssize( vStepInfo) && bHolePocketing ; ++ i) {
bHolePocketing = ( ssize( vStepInfo[i].vPaths) == 1 && vStepInfo[i].vPaths[0].bOptCirle &&
! vStepInfo[i].vPaths[0].bOutStart && ! vStepInfo[i].vPaths[0].bOutEnd) ;
}
// se foro chiuso ed entrata ad elica, aggiusto il raggio massimo
if ( bHolePocketing && m_Params.m_nSubType == POCKET_SUB_SPIRALOUT && GetLeadInType() == POCKET_LI_HELIX) {
@@ -4682,8 +4711,8 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
}
// calcolo la curva di ritorno ( se necessaria)
for ( int i = 0 ; i < int( vStepInfo.size()) ; ++ i) {
for ( int j = 0 ; j < int( vStepInfo[i].vPaths.size()) ; ++ j) {
for ( int i = 0 ; i < ssize( vStepInfo) ; ++ i) {
for ( int j = 0 ; j < ssize( vStepInfo[i].vPaths) ; ++ j) {
if ( GetLeadInType() == POCKET_LI_GLIDE || bHolePocketing) {
PtrOwner<ICurveComposite> pCrvGlideIn( CreateCurveComposite()) ;
if ( IsNull( pCrvGlideIn) ||
@@ -4725,10 +4754,12 @@ PocketingNT::CalcPaths( STEPINFOPOVECTOR& vStepInfo)
bool bOk = true ;
for ( int nC = 0 ; bOk && nC < vStepInfo[i].vPaths[j].pCrvPath->GetCurveCount() ; ++ nC) {
const ICurve* pCrv = vStepInfo[i].vPaths[j].pCrvPath->GetCurve( nC) ;
bOk = ( pCrv != nullptr && pCrv->IsValid() && pCompoZigZag->AddCurve( *pCrv)) ;
Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ;
if ( AreSamePointEpsilon( ptStart, ptEnd, 25. * EPS_SMALL))
break ;
bOk = ( pCrv != nullptr && pCrv->IsValid() && pCompoZigZag->AddCurve( *pCrv)) ;
if ( bOk) {
Point3d ptEnd ; pCrv->GetEndPoint( ptEnd) ;
if ( AreSamePointEpsilon( ptStart, ptEnd, 25. * EPS_SMALL))
break ;
}
}
if ( bOk)
vStepInfo[i].vPaths[j].pCrvZigZagIn.Set( Release( pCompoZigZag)) ;
@@ -4782,6 +4813,276 @@ PocketingNT::ManageSmoothLink( const PathInfoPO& currPath, const PathInfoPO& nex
return true ;
}
//----------------------------------------------------------------------------
bool
PocketingNT::VerifyParallelPocketing( int nDouble, const STEPINFOPOVECTOR& vStepInfo) const
{
// verifico se lavorazione in doppio valida
if ( nDouble != 1 && nDouble != 2 && nDouble != 3)
return false ;
// se non ho piano di pocketing allora non devo fare nulla
if ( vStepInfo.empty())
return false ;
// se la macchina non presenta nel file .ini la possibilità di lavorazione in doppio parallela, esco
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr)
return false ;
string sMachIni = pMch->GetMachineDir() + "\\" + pMch->GetMachineName() + ".ini" ;
int nPocketingDouble = GetPrivateProfileInt( MACHININGS_SEC.c_str(), POCKETING_PARALLEL_KEY.c_str(), 0, sMachIni.c_str()) ;
if ( nPocketingDouble != 1)
return false ;
// recupero il piano di Mirror
Point3d ptOn ; Vector3d vtNorm ;
if ( ! CalcMirrorPlaneByDouble( nDouble, m_Params.m_sUserNotes, ptOn, vtNorm))
return false ;
Plane3d plMirror ;
if ( ! plMirror.Set( ptOn, vtNorm))
return false ;
// recupero il piano dell'ultima svuotatura
bool bOk = false ;
Plane3d plLastStep ;
for ( auto Iter = vStepInfo.rbegin() ; ! bOk && Iter != vStepInfo.rend() ; ++ Iter) {
if ( Iter->pSfrPock != nullptr && Iter->pSfrPock->IsValid()) {
for ( int nPath = 0 ; ! bOk && nPath < ssize( ( *Iter).vPaths) ; ++ nPath) {
if ( ( *Iter).vPaths[nPath].pCrvPath != nullptr && ( *Iter).vPaths[nPath].pCrvPath->IsValid()) {
Point3d ptLastStep ; ( *Iter).pSfrPock->GetCentroid( ptLastStep) ;
bOk = ( plLastStep.Set( ptLastStep, ( *Iter).pSfrPock->GetNormVersor())) ;
}
}
}
}
if ( ! bOk)
return false ;
// verifico subito che la normale del piano si trovi entro un grado rispetto alla direzione di svuotatura ( tolleranza da .BTL)
if ( abs( plLastStep.GetVersN() * vtNorm) < cos( ( 1. - EPS_ANG_SMALL) * DEGTORAD))
return false ;
// se l'ultimo piano di pocketing si trova nel semipiano positivo di Mirroring e sufficientemente distante da esso non eseguo la lavorazione
// in parallelo ( SAFE_DIST_TOL è la distanza tra l'utensile e il piano di Mirror, quindi la distanza tra le due "punte" è il doppio)
const double SAFE_DIST_TOL = 5. ; // -->! distanza tra le punte è il doppio
double dDist = ( plLastStep.GetPoint() - ptOn) * plLastStep.GetVersN() ;
if ( dDist < EPS_SMALL)
return true ;
double dSafeTipDist = m_TParams.m_dTLen - m_TParams.m_dLen ; // nelle svuotature mi aspetto 0.
if ( dDist < dSafeTipDist + SAFE_DIST_TOL)
return true ;
return false ;
}
//----------------------------------------------------------------------------
double
PocketingNT::GetDoubleLastStep( void)
{
// se non è pocketing in doppio, restituisco valore negativo
const double FALSE_LASTSTEP = - EPS_SMALL ;
if ( GetDoubleType( m_Params.m_sUserNotes) == 0)
return FALSE_LASTSTEP ;
// recupero valore
const double MIN_LASTSTEP = 15 ;
double dDoubleLastStep = m_Params.m_dStep ;
if ( GetValInNotes( m_Params.m_sUserNotes, UN_LASTSTEP, dDoubleLastStep))
dDoubleLastStep = max( dDoubleLastStep, MIN_LASTSTEP) ;
return dDoubleLastStep ;
}
//----------------------------------------------------------------------------
bool
PocketingNT::CalcDoubleParallelPenultimateStep( int nDouble, int nIdDblS, double dStep, double dLastStep, const Point3d& ptNeatEnd, const Vector3d& vtEnd,
const INTVECTOR& vLeadOutId, const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool,
bool bSplitArcs, double dMinFeed)
{
// recupero l'ultima entità del percorso
int nIdDblEnd = m_pGeomDB->GetLastInGroup( m_nPathId) ;
if ( nIdDblS > nIdDblEnd)
return false ;
// determino il piano corrente di svuotatura
Plane3d plLastStep ;
if ( ! plLastStep.Set( ptNeatEnd, vtTool))
return false ;
INTVECTOR vIndCrvNotInLastStepPlane ;
// recupero il percorso dell'ultimo piano di pocketing
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
if ( IsNull( pCompo))
return false ;
for ( int nEntId = nIdDblS + 1 ; nEntId <= nIdDblEnd ; ++ nEntId) {
// l'ultimo piano deve essere eseguito in parallelo, quindi modifico il Name delle entità
m_pGeomDB->SetName( nEntId, MCH_CL_PARALLEL_DBL) ;
const ICurve* pCrv = GetCurve( m_pGeomDB->GetGeoObj( nEntId)) ;
if ( pCrv == nullptr || ! pCrv->IsValid())
return false ;
// recupero l'entità camData corrispondente
CamData* pCamData = GetCamData( m_pGeomDB->GetUserObj( nEntId)) ;
if ( pCamData != nullptr) {
double dFeed = pCamData->GetFeed() ;
// verifico se la curva corrente appartiene al piano del LastStep
bool bOnPlane = false ;
Plane3d plCrv ;
if ( pCrv->GetType() == CRV_LINE) {
Point3d ptS ; pCrv->GetStartPoint( ptS) ;
Point3d ptE ; pCrv->GetEndPoint( ptE) ;
if ( DistPointPlane( ptS, plLastStep) < 10. * EPS_SMALL && DistPointPlane( ptE, plLastStep) < 10. * EPS_SMALL)
bOnPlane = true ;
}
else if ( pCrv->IsFlat( plCrv, false, 10. * EPS_SMALL) &&
abs( DistPointPlane( plCrv.GetPoint(), plLastStep)) < 10. * EPS_SMALL &&
AreSameOrOppositeVectorApprox( plCrv.GetVersN(), plLastStep.GetVersN()))
bOnPlane = true ;
if ( ! bOnPlane)
vIndCrvNotInLastStepPlane.push_back( pCompo->GetCurveCount()) ;
else {
// NB : dLastStep non assume valore < 15 per definizione ( GetDoubleLastStep())
if ( dLastStep > dStep + 10. * EPS_SMALL) {
double dNewFeed = Clamp( dFeed * ( dStep / dLastStep), dMinFeed, GetFeed()) ;
pCamData->SetFeed( dNewFeed) ;
}
}
PtrOwner<ICurve> pCurve( pCrv->Clone()) ;
if ( IsNull( pCurve))
return false ;
pCurve->SetTempParam( dFeed, 0) ;
if ( ! pCompo->AddCurve( Release( pCurve)))
return false ;
}
}
#if DEBUG_DOUBLE_PARALLEL
int nCompoBC = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompo->Clone()) ;
m_pGeomDB->SetMaterial( nCompoBC, RED) ;
for ( int i = 0 ; i < ssize( vIndCrvNotInLastStepPlane) ; ++ i) {
const ICurve* pCrv = pCompo->GetCurve( vIndCrvNotInLastStepPlane[i]) ;
int nEntId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCrv->Clone()) ;
m_pGeomDB->SetMaterial( nEntId, YELLOW) ;
}
#endif
// calcolo il piano di Mirror
Point3d ptOn ; Vector3d vtNorm ;
CalcMirrorPlaneByDouble( nDouble, m_Params.m_sUserNotes, ptOn, vtNorm) ;
// dato che l'ultimo piano di svuotatura arriva alla Depth stabilita, bisogna aggiungere un alteriore piano che il secondo
// utensile deve svuotare. Essendo che i percorsi sono calcolati sempre sull'utensile principale, bisogna effettuare un'opportuna
// operazione di traslazione e di Mirror in modo da posizionare il primo utensile in modo tale che il secondo finisca in un piano
// di Pocketing specchiato e alla quota corretta rispetto al piano di Mirror calcolato.
double dDblTrasl = ( ( ptOn - ptNeatEnd) * vtTool) ; // ptNeat in quanto privo di possibile LeadOut
pCompo->Mirror( ptOn, vtNorm) ;
pCompo->Translate( 2. * ( dLastStep - dDblTrasl) * vtTool) ;
#if DEBUG_DOUBLE_PARALLEL
int nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCompo->Clone()) ;
m_pGeomDB->SetMaterial( nId, LIME) ;
#endif
// dopo aver percorso l'ultimo Step devo raccordarmi per raggiungere quest'ultimo
Point3d ptStart ; pCompo->GetStartPoint( ptStart) ;
Vector3d vtStart ; pCompo->GetStartDir( vtStart) ;
// proietto il punto iniziale del percorso di Mirror sul piano di Mirror
Plane3d plMirror ; plMirror.Set( ptOn, vtNorm) ;
Point3d ptStartProj = ProjectPointOnPlane( ptStart, plMirror) ;
Point3d ptCurr ; GetCurrPos( ptCurr) ;
Point3d ptCurrProj = ProjectPointOnPlane( ptCurr, plMirror) ;
// se il punto corrente e la proiezione della destinazione non coincidono, definisco il collegamento
// -->! l'obiettivo è raggiungere ptStart, il punto iniziale del percorso dello Step aggiuntivo
SetFeed( GetStartFeed()) ; // per lo Step in doppio
if ( ! AreSamePointEpsilon( ptStartProj, ptCurrProj, 25. * EPS_SMALL)) {
// --- controllo se un collegamento lineare è valido
PtrOwner<ICurveComposite> pCrvSafeLink( CreateCurveComposite()) ;
if ( IsNull( pCrvSafeLink))
return false ;
pCrvSafeLink->AddPoint( ptCurrProj) ;
pCrvSafeLink->AddLine( ptStartProj) ;
if ( ! pCrvSafeLink->IsValid())
return false ;
bool bSafeLimit = true ;
if ( pSfrLimit != nullptr && pSfrLimit->IsValid()) {
for ( int nC = 0 ; nC < pSfrLimit->GetChunkCount() && bSafeLimit ; ++ nC) {
CRVCVECTOR ccClass ;
bSafeLimit = ( pSfrLimit->GetCurveClassification( *pCrvSafeLink, EPS_SMALL, ccClass) &&
ssize( ccClass) == 1 && ccClass[0].nClass == CRVC_OUT) ;
}
}
// --- altrimenti cerco un percorso di raccordo smussato ed in tangenza
if ( ! bSafeLimit) {
Vector3d vtEndDir = vtEnd ;
int nLastId = m_pGeomDB->GetLastInGroup( m_nPathId) ;
bool bOk = false ;
do {
const ICurve* pCrv = GetCurve( m_pGeomDB->GetGeoObj( nLastId)) ;
bOk = ( pCrv != nullptr && pCrv->IsValid()) ;
if ( bOk) {
pCrv->GetEndDir( vtEndDir) ;
bOk = CheckSafetyLink( ptCurr, vtEndDir, ptStart, vtStart, pSfrLimit, vtTool, false, bSafeLimit, pCrvSafeLink) ;
}
} while ( ! bOk) ;
if ( ! bOk)
return false ;
}
// aggiusto la pendenza della curva di raccordo calcolata
if ( ! IsNull( pCrvSafeLink) && pCrvSafeLink->IsValid()) {
SetFeed( GetEndFeed()) ;
pCrvSafeLink->SetExtrusion( vtTool) ;
double dNini = ( ptCurr - ORIG) * vtTool ;
double dNfin = ( ptStart - ORIG) * vtTool ;
AdjustCurveSlope( pCrvSafeLink, dNini, dNfin) ;
AddCurveMove( pCrvSafeLink, bSplitArcs, MCH_CL_PARALLEL_DBL) ;
}
}
else {
// aggiungo risalita nel vuoto
AddLinearMove( ptStart, bSplitArcs, MCH_CL_PARALLEL_DBL) ;
}
// aggiungo il percorso dello Step Extra ( con le opportune Feed)
for ( int nU = 0 ; nU < pCompo->GetCurveCount() ; ++ nU) {
// curva corrente
const ICurve* pCrvC = pCompo->GetCurve( nU) ;
PtrOwner<ICurve> pCurve( pCrvC->Clone()) ;
if ( IsNull( pCurve))
return false ;
// coefficiente feed ( riduzione di feed per sezione di taglio superiore al previsto )
double dFeed ; pCompo->GetCurveTempParam( nU, dFeed) ; // feed originaria
if ( vIndCrvNotInLastStepPlane.empty() ||
find( vIndCrvNotInLastStepPlane.begin(), vIndCrvNotInLastStepPlane.end(), nU) == vIndCrvNotInLastStepPlane.end()) {
if ( dLastStep - 2. * dDblTrasl > dStep)
dFeed = Clamp( dFeed * ( dStep / ( dLastStep - 2. * dDblTrasl)), dMinFeed, GetFeed()) ;
}
else {
#if DEBUG_DOUBLE_PARALLEL
nId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, pCurve->Clone()) ;
m_pGeomDB->SetMaterial( nId, AQUA) ;
#endif
}
SetFeed( dFeed) ;
// elaborazioni sulla curva corrente
if ( pCurve->GetType() == CRV_LINE) {
ICurveLine* pLine = GetCurveLine( pCurve) ;
Point3d ptP3 = pLine->GetEnd() ;
if ( AddLinearMove( ptP3, bSplitArcs, MCH_CL_PARALLEL_DBL) == GDB_ID_NULL)
return false ;
}
else {
if ( AddCurveMove( pCurve, bSplitArcs, MCH_CL_PARALLEL_DBL) == GDB_ID_NULL)
return false ;
}
}
// aggiungo discesa per movimento di sincronizzazione
GetCurrPos( ptCurr) ;
double dDepth = ( - ( ptNeatEnd - ptCurr) * vtTool) / 2. ;
if ( dDepth > 25. * EPS_SMALL) { // sempre...
SetFeed( GetEndFeed()) ; // ho rimosso tutto il materiale
AddLinearMove( ptCurr - dDepth * vtTool, bSplitArcs, MCH_CL_PARALLEL_DBL) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, double dStep, bool bSplitArcs,
@@ -4820,12 +5121,21 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
if ( GetValInNotes( m_Params.m_sUserNotes, UN_MINFEED, dMinFeed))
dMinFeed = Clamp( dMinFeed, GetFeed() / FEED_MAX_REDUCE, GetFeed()) ;
// verifico se devo eseguire una lavorazione in doppio in parallelo
int nDouble = GetDoubleType( m_Params.m_sUserNotes) ;
bool bDouble = ( nDouble != 0) ;
bool bDoubleParallel = false ;
int nIdDblS = GDB_ID_NULL ;
INTVECTOR vLeadOutIds ;
if ( bDouble)
bDoubleParallel = VerifyParallelPocketing( nDouble, vStepInfo) ;
// scorro il vettore dei piani di pocketing
for ( int i = 0 ; i < int( vStepInfo.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vStepInfo) ; ++ i) {
// riferimento alle informazioni relative allo step i-esimo
StepInfoPO& currStep = vStepInfo[i] ;
// scorro i percorsi calcolati per il piano di pocketing i-esimo
for ( int j = 0 ; j < int( currStep.vPaths.size()) ; ++ j) {
for ( int j = 0 ; j < ssize( currStep.vPaths) ; ++ j) {
// riferimento alle informazioni relative al percorso j-esimo del piano di pocketing i-esimo
PathInfoPO& currPath = currStep.vPaths[j] ;
// ciclo sulle curve elementari del percorso attuale
@@ -4864,7 +5174,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
double dEscapeElev = 0. ;
Vector3d vtEscape ;
if ( bAbsFirst)
CalcFirstElevation( ptStart, ptP1, vtTool, currStep, dSafeZ, dStep, dCurrElev, dEscapeElev, vtEscape) ;
CalcFirstElevation( ptP1, vtTool, currStep, dSafeZ, dStep, dCurrElev, dEscapeElev, vtEscape) ;
bool bEscapeElev = ( dEscapeElev > 10. * EPS_SMALL && vtEscape.Len() > 10. * EPS_SMALL) ;
// sposto il focus su PtP1 per approccio, quindi riduco l'elevazione corrente se esso non coicide con ptStart
dCurrElev -= ( ptP1 - ptStart) * vtTool ;
@@ -4876,7 +5186,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
// se lucidatura forzo il valore al parametro di elevazione in ingresso
if ( m_TParams.m_nType == TT_MILL_POLISHING) {
ptP1 += vtTool * max( m_Params.m_dLiElev, dCurrElev + LIO_ELEV_TOL) ;
dCurrElev = 0 ;
dCurrElev = 0. ;
}
// altrimenti, muovo ptP1 alla quota dell'elevazione corrente
else {
@@ -4902,7 +5212,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
double dMyAppr = ( bAbsFirst ? dAppr : 0.) ;
if ( bAbsFirst || ! OrthoCompo( ptMyPos - ptP1, vtTool).IsSmall()) {
if ( bAbsFirst && bEscapeElev) {
if ( ! AddApproach( ptP1 + vtEscape * dEscapeElev, vtEscape, dMySafeZ, dSafeAggrBottZ, 0, dMyAppr, bSplitArcs, currPath.bOutStart)) {
if ( ! AddApproach( ptP1 + vtEscape * dEscapeElev, vtEscape, dMySafeZ, dSafeAggrBottZ, 0., dMyAppr, bSplitArcs, currPath.bOutStart)) {
m_pMchMgr->SetLastError( 3011, "Error in PocketingNT : Approach not computable") ;
return false ;
}
@@ -4929,7 +5239,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ; pLine->Set( ptCurr, ptP1) ;
DebugDrawFeed( pLine->Clone(), bInMaterial ? GetRightFeed( vtMove, vtTool) : GetStartFeed(), nLayDebugFeed) ;
#endif
AddLinearMove( ptP1) ;
AddLinearMove( ptP1, bSplitArcs) ;
}
bool bNoneForced = ( currPath.bOutStart || currPath.bSingleCrv ||
( m_Params.m_nSubType == POCKET_SUB_ZIGZAG && ! currPath.bIsZigZagOneWayBorder) ||
@@ -4972,20 +5282,35 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
// memorizzo il punto finale della lavorazione
ptPockEnd = ptEnd ;
// aggiungo LeadOut
int nLastId = GDB_ID_NULL ;
if ( bDoubleParallel)
nLastId = m_pGeomDB->GetLastInGroup( m_nPathId) ;
Point3d ptP1 ;
SetFeed( GetEndFeed()) ;
if ( ! AddLeadOut( ptEnd, vtEnd, vtTool, currStep.pSfrPock, currPath.pCrvGlideOut, bSplitArcs, false, ptP1)) {
m_pMchMgr->SetLastError( 3014, "Error in PocketingNT : LeadOut not computable") ;
return false ;
}
/* ---- se lavorazione in Doppio in Parallelo ---- */
if ( bDoubleParallel) {
int nCurrId = m_pGeomDB->GetLastInGroup( m_nPathId) ;
if ( nLastId != nCurrId) {
for ( int nId = nLastId + 1 ; nId <= nCurrId ; ++ nId)
vLeadOutIds.push_back( nId) ;
}
if ( ! CalcDoubleParallelPenultimateStep( nDouble, nIdDblS, dStep, currStep.dRelativeDepth, ptEnd, vtEnd, vLeadOutIds,
currStep.pSfrLimit, vtTool, bSplitArcs, dMinFeed))
return false ;
GetCurrPos( ptEnd) ;
}
// calcolo l'elevazione al di sopra del punto corrente. Esattamente come per la prima elevazione in assoluto potrei
// avere una direzione di 'Escape'
double dLastElev = 0., dEscapeElev = 0. ;
Vector3d vtEscape ;
if ( ! CalcLastElevation( ptEnd, ptP1, vtTool, currStep, dSafeZ, dStep, dLastElev, dEscapeElev, vtEscape))
if ( ! CalcLastElevation( ptP1, vtTool, currStep, dSafeZ, dStep, dLastElev, dEscapeElev, vtEscape))
return false ;
if ( dEscapeElev > 10. * EPS_SMALL && vtEscape.Len() > 10. * EPS_SMALL) {
AddLinearMove( ptP1 + vtTool * dLastElev) ;
AddLinearMove( ptP1 + vtTool * dLastElev, bSplitArcs) ;
if ( ! AddRetract( ptP1 + vtTool * dLastElev, vtEscape, dSafeZ, dSafeAggrBottZ, dEscapeElev, dAppr, bSplitArcs)) {
m_pMchMgr->SetLastError( 3015, "Error in PocketingNT : Retract not computable") ;
return false ;
@@ -5016,6 +5341,11 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
PathToGo.pCrvPath->GetStartPoint( ptDest) ;
PathToGo.pCrvPath->GetStartDir( vtDest) ;
}
/* ---- // ---- se lavorazione in doppio e in parallelo ---- // ---- */
if ( bDoubleParallel && ! bSamePlane) {
if ( ( i + 2) == ssize( vStepInfo) && nIdDblS == GDB_ID_NULL)
nIdDblS = m_pGeomDB->GetLastInGroup( m_nPathId) ;
}
// determino se possibile aggiungere un collegamento smussato
bool bSafeLimit = false, bSmoothEnd = true, bForceLinear = false ;
ManageSmoothLink( currPath, PathToGo, bSamePlane, bSmoothEnd, bForceLinear) ; // verifico solo se fattibile
@@ -5065,7 +5395,7 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
SetFeed( GetEndFeed()) ;
dCurrElev += ( bSafeLimit ? 0. : EXTRA_ELEV) ;
dNextElev += ( bSafeLimit ? 0. : EXTRA_ELEV) ;
// se devo salire lungo vtTool da vtEnd, mi alzo
// se devo salire lungo vtTool da ptEnd, mi alzo
if ( dCurrElev > EPS_SMALL)
AddLinearMove( ptEnd + dCurrElev * vtTool, bSplitArcs) ;
// mi dirigo sopra a ptDest
@@ -5093,25 +5423,25 @@ PocketingNT::AddPocket( STEPINFOPOVECTOR& vStepInfo, const Vector3d& vtTool, dou
//----------------------------------------------------------------------------
bool
PocketingNT::CalcFirstElevation( const Point3d& ptStart, const Point3d& ptP1, const Vector3d& vtTool,
PocketingNT::CalcFirstElevation( const Point3d& ptP1, const Vector3d& vtTool,
const StepInfoPO& currStep, double dSafeZ, double dStep, double& dCurrElev,
double& dEscapeElev, Vector3d& vtEscape) const
{
// elevazione per ingresso
if ( ! GetElevation( m_nPhase, ptP1 - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dCurrElev))
dCurrElev = currStep.dDepth + 10 * EPS_SMALL ;
if ( ! GetElevation( m_nPhase, ptP1 - 10. * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dCurrElev))
dCurrElev = currStep.dDepth + 10. * EPS_SMALL ;
else
dCurrElev = max( dCurrElev, currStep.dDepth + 10 * EPS_SMALL) ;
dEscapeElev = 0 ;
dCurrElev = max( dCurrElev, currStep.dDepth + 10. * EPS_SMALL) ;
dEscapeElev = 0. ;
vtEscape = V_NULL ;
double dMyEscapeElev = 0 ;
double dMyEscapeElev = 0. ;
Vector3d vtMyEscape = vtTool ;
vtMyEscape.z = ( m_bAboveHead ? max( vtTool.z, 0.) : min( vtTool.z, 0.)) ;
bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab &&
GetAhPointUnderRaw( ptP1 + dCurrElev * vtTool, vtTool, 0, GetRadiusForStartEndElevation(),
GetAhPointUnderRaw( ptP1 + dCurrElev * vtTool, vtTool, 0., GetRadiusForStartEndElevation(),
m_TParams.m_dLen, false, dSafeZ, vtMyEscape, dMyEscapeElev) ;
bool bUhAboveRaw = ! m_bAboveHead &&
GetUhPointAboveRaw( ptP1 + dCurrElev * vtTool, vtTool, 0, GetRadiusForStartEndElevation(),
GetUhPointAboveRaw( ptP1 + dCurrElev * vtTool, vtTool, 0., GetRadiusForStartEndElevation(),
m_TParams.m_dLen, false, dSafeZ, vtMyEscape, dMyEscapeElev) ;
if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab) {
dEscapeElev = dMyEscapeElev ;
@@ -5123,22 +5453,22 @@ PocketingNT::CalcFirstElevation( const Point3d& ptStart, const Point3d& ptP1, co
//----------------------------------------------------------------------------
bool
PocketingNT::CalcLastElevation( const Point3d& ptEnd, const Point3d& ptP1, const Vector3d& vtTool, const StepInfoPO& currStep,
PocketingNT::CalcLastElevation( const Point3d& ptP1, const Vector3d& vtTool, const StepInfoPO& currStep,
double dSafeZ, double dStep, double& dCurrElev, double& dEscapeElev, Vector3d& vtEscape) const
{
// elevazione per uscita
if ( ! GetElevation( m_nPhase, ptP1, vtTool, GetRadiusForStartEndElevation(), m_TParams.m_dLen, vtTool, dCurrElev))
dCurrElev = currStep.dDepth ;
dEscapeElev = 0 ;
dEscapeElev = 0. ;
vtEscape = V_NULL ;
double dMyEscapeElev = 0 ;
double dMyEscapeElev = 0. ;
Vector3d vtMyEscape = vtTool ;
vtMyEscape.z = ( m_bAboveHead ? max( vtTool.z, 0.) : min( vtTool.z, 0.)) ;
bool bAhUnderRaw = m_bAboveHead && ! m_bAggrBottom && ! m_bTiltingTab &&
GetAhPointUnderRaw( ptP1 + vtTool * dCurrElev, vtTool, 0, GetRadiusForStartEndElevation(),
GetAhPointUnderRaw( ptP1 + vtTool * dCurrElev, vtTool, 0., GetRadiusForStartEndElevation(),
m_TParams.m_dLen, false, dSafeZ, vtMyEscape, dMyEscapeElev) ;
bool bUhAboveRaw = ! m_bAboveHead &&
GetUhPointAboveRaw( ptP1 + vtTool * dCurrElev, vtTool, 0, GetRadiusForStartEndElevation(),
GetUhPointAboveRaw( ptP1 + vtTool * dCurrElev, vtTool, 0., GetRadiusForStartEndElevation(),
m_TParams.m_dLen, false, dSafeZ, vtMyEscape, dMyEscapeElev) ;
if ( bAhUnderRaw || bUhAboveRaw || m_bTiltingTab) {
dEscapeElev = dMyEscapeElev ;
@@ -5876,7 +6206,7 @@ PocketingNT::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vect
double dNfin = ( ptFin - ORIG) * vtN ;
AdjustCurveSlope( pCrv, dNini, dNfin) ;
// emetto (con eventuale spezzatura)
if ( AddCurveMove( pCrv, bSplitArcs, MCH_CL_LEADIN) == GDB_ID_NULL)
if ( AddCurveMove( pCrv, bSplitArcs, MCH_CL_LEADOUT) == GDB_ID_NULL)
return false ;
ptP1 = ptFin ;
}
@@ -6170,7 +6500,6 @@ PocketingNT::AddSpecialLeadInZigZag( const ICurveComposite* pCompoPath, const Po
if ( ! pCompoPath->IsPointOn( ptCurr, TOL))
return false ;
Point3d ptStartZigZag = ptCurr ; // punto di inizio dello ZigZag ( potrebbe essere diverso da ptCurr)
bool bAtStart = false ; // indica se lo ZigZag è vincolato prima della partenza
bool bAtEnd = false ; // indica se lo ZigZag è vincolato dopo l'arrivo
+7 -2
View File
@@ -152,10 +152,10 @@ class PocketingNT : public Machining
double dElev, double dAppr, bool bSplitArcs) ;
bool AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dSafeAggrBottZ,
double dElev, double dAppr, bool bSplitArcs) ;
bool CalcFirstElevation( const Point3d& ptStart, const Point3d& ptP1, const Vector3d& vtTool,
bool CalcFirstElevation( const Point3d& ptP1, const Vector3d& vtTool,
const StepInfoPO& currStep, double dSafeZ, double dStep, double& dCurrElev,
double& dEscapeElev, Vector3d& vtEscape) const ;
bool CalcLastElevation( const Point3d& ptStart, const Point3d& ptP1, const Vector3d& vtTool,
bool CalcLastElevation( const Point3d& ptP1, const Vector3d& vtTool,
const StepInfoPO& currStep, double dSafeZ, double dStep, double& dCurrElev,
double& dEscapeElev, Vector3d& vtEscape) const ;
bool CalcLeadInStart( Point3d& ptStart, const Vector3d& vtTool, const ICurveComposite* pCrvPath, Point3d& ptP1) ;
@@ -177,6 +177,11 @@ class PocketingNT : public Machining
bool VerifyLeadInOutGlide( const ISurfFlatRegion* pSfr, ICurveComposite* pCrvGlide) ;
bool AddSpecialLeadInZigZag( const ICurveComposite* pCompoPath, const Point3d& ptStart, const Vector3d& vtTool, int nStep, double dStep) ;
bool CalcDistanceFromRawSurface( int nPhase, const Point3d& ptP, const Vector3d& vtDir, double& dDist, Vector3d& vtNorm) ;
bool VerifyParallelPocketing( int nDouble, const STEPINFOPOVECTOR& vStepInfo) const ;
bool CalcDoubleParallelPenultimateStep( int nDouble, int nIdDblS, double dStep, double dLastStep, const Point3d& ptNeatEnd, const Vector3d& vtEnd,
const INTVECTOR& vLeadOutId, const ISurfFlatRegion* pSfrLimit, const Vector3d& vtTool,
bool bSplitArcs, double dMinFeed) ;
double GetDoubleLastStep( void) ;
// debug
void DebugDrawSfr( const ISurfFlatRegion* pSfr, bool bUniform, int nlayer = GDB_ID_ROOT) ;
void DebugDrawLoop( const ICurveComposite* pCrvCompo, int nLayer, bool bUniform) ;