EgtMachKernel 2.6f1 :

- modifiche per sgrossatura superfici.
This commit is contained in:
Dario Sassi
2024-06-03 08:16:08 +02:00
parent 9c73479441
commit 8c4c606ee1
4 changed files with 113 additions and 634 deletions
BIN
View File
Binary file not shown.
+1 -2
View File
@@ -26,8 +26,7 @@
#include "/EgtDev/Include/EGkArcSpecial.h"
#include "/EgtDev/Include/EGkChainCurves.h"
#include "/EgtDev/Include/EGkOffsetCurve.h"
#include "/EgtDev/Include/EGkOffsetCurveOnX.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkSurfLocal.h"
#include "/EgtDev/Include/EGkCAvToolSurfTm.h"
#include "/EgtDev/Include/EGkIntervals.h"
+110 -623
View File
@@ -26,10 +26,9 @@
#include "/EgtDev/Include/EGkArcSpecial.h"
#include "/EgtDev/Include/EGkChainCurves.h"
#include "/EgtDev/Include/EGkOffsetCurve.h"
#include "/EgtDev/Include/EGkOffsetCurveOnX.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkSurfLocal.h"
#include "/EgtDev/Include/EGkCAvToolSurfTm.h"
#include "/EgtDev/Include/EGkCalcPocketing.h"
#include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkUserObjFactory.h"
@@ -63,6 +62,8 @@ using namespace std ;
// 3020 = "Error in SurfRoughing : post apply not calculable"
// 3021 = "Error in SurfRoughing : Linear Approx not computable"
// 3022 = "Error in SurfRoughing : aggregate from bottom not allowed"
// 3023 = "Error in SurfRoughing : missing surfaces"
// 3024 = "Error in SurfRoughing : region not computable"
// 3051 = "Warning in SurfRoughing : Skipped entity (xx)"
// 3052 = "Warning in SurfRoughing : No machinable path"
// 3053 = "Warning in SurfRoughing : Tool name changed (xx)"
@@ -574,11 +575,28 @@ SurfRoughing::Apply( bool bRecalc, bool bPostApply)
else
m_pGeomDB->EmptyGroup( nClId) ;
// recupero gruppo per geometria temporanea
const string GRP_TEMP = "Temp" ;
int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ;
// se non c'è, lo aggiungo
if ( nTempId == GDB_ID_NULL) {
nTempId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ;
if ( nTempId == GDB_ID_NULL)
return false ;
m_pGeomDB->SetName( nTempId, GRP_TEMP) ;
}
// altrimenti lo svuoto
else
m_pGeomDB->EmptyGroup( nTempId) ;
// in ogni caso lo dichiaro temporaneo e non visibile
m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ;
m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ;
// lavoro ogni singola catena
bool bOk = true ;
int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ;
while ( nPathId != GDB_ID_NULL) {
if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId))
if ( ! ProcessPath( nPathId, nTempId, GDB_ID_NULL, nClId))
bOk = false ;
nPathId = m_pGeomDB->GetNextGroup( nPathId) ;
}
@@ -1090,25 +1108,8 @@ SurfRoughing::Chain( int nGrpDestId)
//----------------------------------------------------------------------------
bool
SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId)
SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId)
{
// recupero gruppo per geometria temporanea
const string GRP_TEMP = "Temp" ;
int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ;
// se non c'è, lo aggiungo
if ( nTempId == GDB_ID_NULL) {
nTempId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ;
if ( nTempId == GDB_ID_NULL)
return false ;
m_pGeomDB->SetName( nTempId, GRP_TEMP) ;
}
// altrimenti lo svuoto
else
m_pGeomDB->EmptyGroup( nTempId) ;
// in ogni caso lo dichiaro temporaneo e non visibile
m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ;
m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ;
// verifico sia una curva chiusa (deve delimitare l'area da svuotare)
int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ;
if ( m_pGeomDB->GetGeoType( nCrvId) != CRV_COMPO)
@@ -1143,6 +1144,8 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId)
}
if ( plPlane.GetVersN() * vtExtr * dArea < 0)
pCompo->Invert() ;
if ( plPlane.GetVersN() * vtExtr < 0)
plPlane.Invert() ;
// unisco le parti allineate
if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true))
@@ -1164,6 +1167,9 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId)
return false ;
}
// verifico ed eventualmente aggiusto lo step
double dOkStep = min( m_Params.m_dStep, m_TParams.m_dMaxMat + EPS_SMALL) ;
// recupero nome del path
string sPathName ;
m_pGeomDB->GetName( nPathId, sPathName) ;
@@ -1171,6 +1177,8 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId)
// assegno il versore fresa
Vector3d vtTool = vtExtr ;
// non prevista gestione anteprima di lavorazione
// se richiesta lavorazione
if ( nClId != GDB_ID_NULL) {
// creo gruppo per geometria di lavorazione del percorso
@@ -1183,55 +1191,61 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId)
// verifico se archi vanno approssimati con segmenti di retta
bool bSplitArcs = GetSplitArcs( vtTool) ;
// predispongo l'ambiente di correzione dei percorsi utensili con le superfici attive dei pezzi
PtrOwner<ICAvToolSurfTm> pCAvTlStm( CreateCAvToolSurfTm()) ;
if ( IsNull( pCAvTlStm))
return false ;
if ( abs( m_TParams.m_dSideAng) < EPS_ANG_SMALL) {
pCAvTlStm->SetStdTool( m_TParams.m_dLen + GetOffsR(),
m_TParams.m_dDiam / 2 + GetOffsR(),
m_TParams.m_dCornRad + GetOffsR()) ;
}
else {
double dDelta ;
double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ;
if ( m_TParams.m_dSideAng > 0) {
if ( m_TParams.m_dCornRad < EPS_SMALL)
dDelta = 2 * m_TParams.m_dMaxMat * tan( dSideAngRad) ;
else
dDelta = 2 * ( m_TParams.m_dCornRad * cos( dSideAngRad) +
( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad)) ;
}
else {
dDelta = 2 * tan( dSideAngRad) * m_TParams.m_dMaxMat ;
}
double dStemRad = m_TParams.m_dDiam / 2 + dDelta ;
double dTipRad = m_TParams.m_dDiam / 2 ;
pCAvTlStm->SetAdvTool( m_TParams.m_dLen + GetOffsR(),
dStemRad + GetOffsR(),
m_TParams.m_dMaxMat,
dTipRad + GetOffsR(),
m_TParams.m_dCornRad + GetOffsR()) ;
}
Frame3d frSurf ;
const ISurfTriMesh* pStm = nullptr ;
SURFLOCALVECTOR vSrfLoc ;
// recupero le superfici attive
INTVECTOR vSurfId ;
GetActiveSurfaces( vSurfId) ;
for ( auto nSurfId : vSurfId) {
if ( pStm == nullptr) {
pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nSurfId)) ;
if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf))
return false ;
pCAvTlStm->SetSurfTm( *pStm) ;
if ( vSurfId.empty()) {
m_pMchMgr->SetLastError( 3023, "Error in SurfRoughing : missing surfaces") ;
return false ;
}
// calcolo le regioni di svuotatura alle varie quote come differenza tra regioni da lavorare e regioni di silhouette
INTVECTOR vPocket ;
const double SILH_TOL = max( GetOffsR(), 1.) ;
int nStep = max( 1, static_cast<int>( ceil( dDepth / dOkStep))) ;
double dStep = dDepth / nStep ;
for ( int i = 1 ; i <= nStep ; ++ i) {
// regione di lavoro allo step corrente
PtrOwner<ISurfFlatRegion> pSfr( CreateSurfFlatRegion()) ;
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( *pCompo)) {
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
return false ;
}
else {
vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ;
pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc.back().Get())) ;
pSfr->Translate( -i * dStep * vtTool) ;
// piano di taglio per silhouette (compreso di offset longitudinale)
Plane3d plCut = plPlane ;
plCut.Translate( - ( i * dStep + GetOffsL()) * vtTool) ;
// per ogni superficie
for ( int nSurfId : vSurfId) {
const ISurfTriMesh* pSurf = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nSurfId)) ;
Frame3d frSurf ; m_pGeomDB->GetGlobFrame( nSurfId, frSurf) ;
Plane3d plCutL = plCut ; plCutL.ToLoc( frSurf) ;
// determino le regioni da non lavorare e le sottraggo
POLYLINEVECTOR vPL ;
if ( pSurf == nullptr || ! pSurf->GetSilhouette( plCutL, SILH_TOL, vPL)) {
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
return false ;
}
for ( auto& PL : vPL) {
PtrOwner<ISurfFlatRegion> pSfrSil( GetSurfFlatRegionFromPolyLine( PL)) ;
if ( IsNull( pSfrSil)) {
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
return false ;
}
pSfrSil->ToGlob( frSurf) ;
pSfr->Subtract( *pSfrSil) ;
}
}
// se regione risultante non vuota, la salvo nel gruppo temporaneo
if ( pSfr->IsValid()) {
int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfr)) ;
if ( nNewId == GDB_ID_NULL) {
m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ;
return false ;
}
vPocket.emplace_back( nNewId) ;
}
}
if ( pStm == nullptr)
pCAvTlStm.Reset() ;
// assegno il vettore estrazione al gruppo del percorso
m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ;
@@ -1240,23 +1254,10 @@ SurfRoughing::ProcessPath( int nPathId, int nPvId, int nClId)
SetPathId( nPxId) ;
SetToolDir( vtTool) ;
// Eseguo la lavorazione a seconda del tipo
// Eseguo le svuotature
double dElev = dDepth ;
switch ( m_Params.m_nSubType) {
case SURFFIN_SUB_ONEWAY :
case SURFFIN_SUB_ZIGZAG :
if ( ! AddZigZag( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs))
return false ;
break ;
case SURFFIN_SUB_SPIRALIN :
if ( ! AddSpiral( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs, true))
return false ;
break ;
case SURFFIN_SUB_SPIRALOUT :
if ( ! AddSpiral( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs, false))
return false ;
break ;
}
if ( ! AddPocket( vPocket, vtTool, vtExtr, dDepth, dElev, bSplitArcs))
return false ;
}
// incremento numero di percorsi
@@ -1316,80 +1317,25 @@ SurfRoughing::GetActiveSurfaces( INTVECTOR& vSurfId) const
//----------------------------------------------------------------------------
bool
SurfRoughing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, bool bSplitArcs)
SurfRoughing::AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, bool bSplitArcs)
{
// recupero distanze di sicurezza
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
// calcolo curva offsettata del raggio utensile
double dOffs = - 0.5 * m_TParams.m_dDiam ;
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCompo, dOffs, ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 3009, "Error in SurfRoughing : Offset not computable") ;
return false ;
}
// ciclo sulle curve risultanti
// ciclo sulle regioni
bool bStart = true ;
while ( OffsCrv.GetCurveCount() > 0) {
// recupero la prima curva di offset
PtrOwner<ICurveComposite> pOffs ;
if ( ! pOffs.Set( ConvertCurveToComposite( OffsCrv.GetLongerCurve()))) {
m_pMchMgr->SetLastError( 3010, "Error in SurfRoughing : Toolpath not computable") ;
return false ;
}
// determino il riferimento di base e il box della svuotatura
Frame3d frPocket ;
Point3d ptCen ; pCompo->GetCentroid( ptCen) ;
frPocket.Set( ptCen, vtExtr) ;
frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ;
pOffs->ToLoc( frPocket) ;
// calcolo i percorsi di svuotatura
for ( int nPockId : vPocket) {
// calcolo la svuotatura
const ISurfFlatRegion* pSfr = GetSurfFlatRegion( m_pGeomDB->GetGeoObj( nPockId)) ;
ICRVCOMPOPOVECTOR vpCrvs ;
if ( ! CalcZigZag( pOffs, vpCrvs))
if ( ! CalcPocketing( pSfr, m_TParams.m_dDiam / 2, m_Params.m_dSideStep, m_Params.m_dSideAngle,
m_Params.m_nSubType, true, vpCrvs))
return false ;
// ciclo sui percorsi
for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) {
// li correggo per non interferire con le superfici
if ( pCAvTlStm != nullptr) {
// approssimo la curva con una polilinea
PolyLine PL ;
if ( ! vpCrvs[k]->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))
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
vpCrvs[k].Set( pCompo) ;
}
// ciclo sulle curve elementari
int nMaxInd = vpCrvs[k]->GetCurveCount() - 1 ;
for ( int i = 0 ; i <= nMaxInd ; ++ i) {
@@ -1399,7 +1345,6 @@ SurfRoughing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
PtrOwner<ICurve> pCurve( pCrvC->Clone()) ;
if ( IsNull( pCurve))
return false ;
pCurve->ToGlob( frPocket) ;
// se prima entità
if ( i == 0 ) {
// dati inizio entità
@@ -1439,14 +1384,25 @@ SurfRoughing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
}
}
// elaborazioni sulla curva corrente (sempre un segmento di retta)
ICurveLine* pLine = GetCurveLine( pCurve) ;
if ( pLine == nullptr)
return false ;
Point3d ptP3 = pLine->GetEnd() ;
Vector3d vtMove ; pLine->GetStartDir( vtMove) ;
SetFeed( GetRightFeed( vtMove, vtTool)) ;
if ( AddLinearMove( ptP3) == GDB_ID_NULL)
return false ;
if ( pCurve->GetType() == CRV_LINE) {
ICurveLine* pLine = GetCurveLine( pCurve) ;
Point3d ptP3 = pLine->GetEnd() ;
Vector3d vtMove ; pLine->GetStartDir( vtMove) ;
SetFeed( GetRightFeed( vtMove, vtTool)) ;
if ( AddLinearMove( ptP3) == GDB_ID_NULL)
return false ;
}
else if ( pCurve->GetType() == CRV_ARC) {
ICurveArc* pArc = GetCurveArc( pCurve) ;
Point3d ptCen = pArc->GetCenter() ;
double dAngCen = pArc->GetAngCenter() ;
Vector3d vtN = pArc->GetNormVersor() ;
Point3d ptP3 ;
pArc->GetEndPoint( ptP3) ;
SetFeed( GetFeed()) ;
if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL)
return false ;
}
// se ultima entità
if ( i == nMaxInd) {
// dati fine entità
@@ -1487,475 +1443,6 @@ SurfRoughing::AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
return true ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::CalcZigZag( const ICurveComposite* pOffs,
ICRVCOMPOPOVECTOR& vpCrvs)
{
// ingombro del contorno offsettato
BBox3d b3Pocket ;
pOffs->GetLocalBBox( b3Pocket) ;
Point3d ptMin ; double dDimX, dDimY, dDimZ ;
b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ;
// lunghezza del contorno offsettato
double dLen ; pOffs->GetLength( dLen) ;
// passi in Y
int nYStep = static_cast<int>( ceil( ( dDimY - 20 * EPS_SMALL) / GetSideStep())) ;
double dYStep = ( nYStep > 0 ? ( dDimY - 20 * EPS_SMALL) / nYStep : 0) ;
// tratto valido
struct Section {
bool bActive ;
Point3d ptS ;
Point3d ptE ;
double dOs ;
double dOe ;
} ;
// raccolta di tratti
typedef vector<vector<Section>> VECVECSECT ;
VECVECSECT vvSec ;
vvSec.resize( nYStep + 1) ;
// calcolo le linee di svuotatura
int nCount = 0 ;
for ( int i = 0 ; i <= nYStep ; ++ i) {
// determino senso
bool bPlus = (( i % 2) == 0) ;
// definisco la linea
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
const double EXP_LEN = 1.0 ;
Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + 10 * EPS_SMALL + i * dYStep, ptMin.z + dDimZ) ;
if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX, dDimX + 2 * EXP_LEN)) {
m_pMchMgr->SetLastError( 3010, "Error in SurfRoughing : Toolpath not computable") ;
return false ;
}
// calcolo la classificazione della curva rispetto al contorno esterno offsettato
IntersCurveCurve intCC( *pLine, *pOffs) ;
CRVCVECTOR ccClass ;
if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) {
m_pMchMgr->SetLastError( 3010, "Error in SurfRoughing : Toolpath not computable") ;
return false ;
}
// determino gli intervalli di curva da conservare
Intervals inOk ;
for ( auto& ccOne : ccClass) {
if ( ccOne.nClass == CRVC_IN || ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M)
inOk.Add( ccOne.dParS, ccOne.dParE) ;
}
// inserisco i tratti validi (secondo X+ i pari, secondo X- i dispari)
double dParS, dParE ;
bool bFound = ( bPlus ? inOk.GetFirst( dParS, dParE) : inOk.GetLast( dParE, dParS)) ;
while ( bFound) {
// determino i dati della sezione
Section Sect ;
Sect.bActive = true ;
pLine->GetPointD1D2( dParS, ICurve::FROM_PLUS, Sect.ptS) ;
pLine->GetPointD1D2( dParE, ICurve::FROM_MINUS, Sect.ptE) ;
pOffs->GetParamAtPoint( Sect.ptS, Sect.dOs, 10 * EPS_SMALL) ;
pOffs->GetParamAtPoint( Sect.ptE, Sect.dOe, 10 * EPS_SMALL) ;
// inserisco nel contenitore
vvSec[i].emplace_back( Sect) ;
++ nCount ;
// recupero successivo intervallo
bFound = ( bPlus ? inOk.GetNext( dParS, dParE) : inOk.GetPrev( dParE, dParS)) ;
}
}
// dominio del contorno
double dUmin, dUmax ;
pOffs->GetDomain( dUmin, dUmax) ;
double dUspan = dUmax - dUmin ;
// creo i percorsi di svuotatura
vpCrvs.reserve( nCount) ;
int nI = -1, nJ = -1 ;
while ( true) {
// se sezione non valida
if ( nI < 0 || nJ < 0) {
// ricerco la prima valida
for ( int k = 0 ; k < int( vvSec.size()) && nI < 0 ; ++ k) {
for ( int l = 0 ; l < int( vvSec[k].size()) && nJ < 0 ; ++ l) {
if ( vvSec[k][l].bActive) {
nI = k ;
nJ = l ;
}
}
}
// se trovata, creo nuova curva composita
if ( nI >= 0 && nJ >= 0) {
// creo la curva
vpCrvs.emplace_back( CreateCurveComposite()) ;
// aggiungo punto iniziale
vpCrvs.back()->AddPoint( vvSec[nI][nJ].ptS) ;
}
// altrimenti, esco
else
break ;
}
// determino senso
bool bPlus = (( nI % 2) == 0) ;
// aggiungo la sezione alla curva
Section& Sec = vvSec[nI][nJ] ;
Sec.bActive = false ;
vpCrvs.back()->AddLine( vvSec[nI][nJ].ptE) ;
// cerco nella stessa fila o in quella successiva sezione successiva raccordabile tramite il contorno
double dUstart = Sec.dOe ;
double dUref = ( bPlus ? INFINITO : - INFINITO) ;
int nNextI = -1 ;
int nNextJ = -1 ;
int li = nJ + 1 ;
for ( int k = nI ; k <= nI + 1 && k < int( vvSec.size()) ; ++ k) {
for ( int l = li ; l < int( vvSec[k].size()) ; ++ l) {
if ( ! vvSec[k][l].bActive)
continue ;
double dU = vvSec[k][l].dOs ;
if ( bPlus) {
if ( dU < dUstart)
dU += dUspan ;
if ( dU < dUref) {
dUref = dU ;
nNextI = k ;
nNextJ = l ;
}
}
else {
if ( dU > dUstart)
dU -= dUspan ;
if ( dU > dUref) {
dUref = dU ;
nNextI = k ;
nNextJ = l ;
}
}
}
li = 0 ;
}
// se trovato, aggiungo il tratto di contorno e continuo
if ( nNextI != -1) {
PtrOwner<ICurve> pCopy ;
if ( bPlus) {
if ( dUref > dUmax)
dUref -= dUspan ;
pCopy.Set( pOffs->CopyParamRange( dUstart, dUref)) ;
if ( ! IsNull( pCopy)) {
double dCLen ; pCopy->GetLength( dCLen) ;
if ( dCLen > 0.5 * dLen) {
pCopy.Set( pOffs->CopyParamRange( dUref, dUstart)) ;
if ( ! IsNull( pCopy))
pCopy->Invert() ;
}
}
}
else {
if ( dUref < dUmin)
dUref += dUspan ;
pCopy.Set( pOffs->CopyParamRange( dUref, dUstart)) ;
if ( ! IsNull( pCopy)) {
pCopy->Invert() ;
double dCLen ; pCopy->GetLength( dCLen) ;
if ( dCLen > 0.5 * dLen)
pCopy.Set( pOffs->CopyParamRange( dUstart, dUref)) ;
}
}
BBox3d b3Copy ;
if ( ! IsNull( pCopy))
pCopy->GetLocalBBox( b3Copy) ;
if ( ! b3Copy.IsEmpty() && ( b3Copy.GetMax().y - b3Copy.GetMin().y) < dYStep + 10 * EPS_SMALL) {
vpCrvs.back()->AddCurve( Release( pCopy)) ;
nI = nNextI ;
nJ = nNextJ ;
}
else {
nI = -1 ;
nJ = -1 ;
}
}
else {
nI = -1 ;
nJ = -1 ;
}
}
// se richiesta percorrenza invertita
if ( m_Params.m_bInvert) {
for ( auto& pCompo : vpCrvs)
pCompo->Invert() ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, bool bSplitArcs, bool bInVsOut)
{
// recupero distanze di sicurezza
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
// calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine
PtrOwner<ICurveComposite> pMCrv( CreateCurveComposite()) ;
if ( IsNull( pMCrv)) {
m_pMchMgr->SetLastError( 3009, "Error in SurfRoughing : Offset not computable") ;
return false ;
}
if ( ! CalcSpiral( pCompo, false, pMCrv, nullptr))
return false ;
if ( ! bInVsOut)
pMCrv->Invert() ;
// ciclo sulle curve risultanti
bool bStart = true ;
if ( true) {
// determino il riferimento di base e il box della svuotatura
Frame3d frPocket ;
Point3d ptCen ; pCompo->GetCentroid( ptCen) ;
frPocket.Set( ptCen, vtExtr) ;
frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ;
pMCrv->ToLoc( frPocket) ;
// ciclo sui percorsi
if ( true) {
// li correggo per non interferire con le superfici
if ( pCAvTlStm != nullptr) {
// approssimo la curva con una polilinea
PolyLine PL ;
if ( ! pMCrv->ApproxWithLines( m_Params.m_dApprox, 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))
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
pMCrv.Set( pCompo) ;
}
// ciclo sulle curve elementari
int nMaxInd = pMCrv->GetCurveCount() - 1 ;
for ( int i = 0 ; i <= nMaxInd ; ++ i) {
// curva corrente
const ICurve* pCrvC = pMCrv->GetCurve( i) ;
// copio la curva
PtrOwner<ICurve> pCurve( pCrvC->Clone()) ;
if ( IsNull( pCurve))
return false ;
pCurve->ToGlob( frPocket) ;
// se prima entità
if ( i == 0 ) {
// dati inizio entità
Point3d ptStart ;
pCurve->GetStartPoint( ptStart) ;
Vector3d vtStart ;
pCurve->GetStartDir( vtStart) ;
// determino inizio attacco
Point3d ptP1 ;
if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, ptP1))
return false ;
// determino elevazione su inizio attacco
double dStElev ;
if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev))
dStElev = dElev ;
dStElev -= ( ptP1 - ptStart) * vtExtr ;
// se inizio, approccio globale al punto iniziale
if ( bStart) {
if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) {
m_pMchMgr->SetLastError( 3011, "Error in SurfRoughing : Approach not computable") ;
return false ;
}
bStart = false ;
}
// altrimenti, approccio di collegamento
else {
if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) {
m_pMchMgr->SetLastError( 3012, "Error in SurfRoughing : Link not computable") ;
return false ;
}
}
// aggiungo attacco
SetFeed( GetStartFeed()) ;
if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bSplitArcs)) {
m_pMchMgr->SetLastError( 3013, "Error in SurfRoughing : LeadIn not computable") ;
return false ;
}
}
// elaborazioni sulla curva corrente (sempre un segmento di retta)
ICurveLine* pLine = GetCurveLine( pCurve) ;
if ( pLine == nullptr)
return false ;
Point3d ptP3 = pLine->GetEnd() ;
Vector3d vtMove ; pLine->GetStartDir( vtMove) ;
SetFeed( GetRightFeed( vtMove, vtTool)) ;
if ( AddLinearMove( ptP3) == GDB_ID_NULL)
return false ;
// se ultima entità
if ( i == nMaxInd) {
// dati fine entità
Point3d ptEnd ;
pCurve->GetEndPoint( ptEnd) ;
Vector3d vtEnd ;
pCurve->GetEndDir( vtEnd) ;
// determino elevazione su uscita
double dEndElev ;
if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev))
dEndElev = dElev ;
// aggiungo uscita
Point3d ptP1 ;
SetFeed( GetEndFeed()) ;
if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, ptP1, bSplitArcs)) {
m_pMchMgr->SetLastError( 3014, "Error in SurfRoughing : LeadOut not computable") ;
return false ;
}
// se non è ultimo tratto, aggiungo retrazione di collegamento
if ( false) {
if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) {
m_pMchMgr->SetLastError( 3012, "Error in SurfRoughing : Link not computable") ;
return false ;
}
}
// altrimenti aggiungo retrazione finale
else {
if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) {
m_pMchMgr->SetLastError( 3015, "Error in SurfRoughing : Retract not computable") ;
return false ;
}
}
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
static double
GetCurveRadius( const ICurve* pCrv)
{
if ( pCrv == nullptr)
return 0.0 ;
BBox3d b3Loc ;
if ( ! pCrv->GetLocalBBox( b3Loc, BBF_EXACT))
return 0.0 ;
double dRad ;
if ( ! b3Loc.GetRadius( dRad))
return 0.0 ;
return dRad ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::CalcSpiral( const ICurveComposite* pCompo, bool bSplitArcs,
ICurveComposite* pMCrv, ICurveComposite* pRCrv)
{
// primo offset pari al raggio utensile - overlap
double dTRad = 0.5 * m_TParams.m_dDiam ;
double dOffs = dTRad ;
// ciclo di offset verso l'interno
const int MAX_ITER = 1000 ;
int nIter = 0 ;
PtrOwner<ICurve> pOffs ;
const ICurve* pCurr = pCompo ;
double dCurrRad = GetCurveRadius( pCurr) ;
while ( nIter < MAX_ITER) {
// calcolo
OffsetCurve OffsCrv ;
if ( ! OffsCrv.Make( pCurr, - dOffs, ICurve::OFF_FILLET)) {
m_pMchMgr->SetLastError( 3009, "Error in SurfRoughing : Offset not computable") ;
return false ;
}
// recupero la prima curva di offset
PtrOwner<ICurve> pNextOffs( OffsCrv.GetLongerCurve()) ;
double dRad = GetCurveRadius( pNextOffs) ;
bool bNextOk = ( dRad > EPS_ZERO && dRad < dCurrRad) ;
bool bSmallRad = ( nIter == 0 ? dOffs < dTRad + EPS_ZERO : dOffs < dTRad + EPS_ZERO) ;
// se completato step di offset, accodo la curva offsettata al percorso di lavoro
if ( ! IsNull( pOffs) && ( bNextOk || bSmallRad)) {
// verifico se aggiungere linea di congiunzione
if ( pMCrv->GetCurveCount() > 0) {
Point3d ptStart ;
pOffs->GetStartPoint( ptStart) ;
// aggiungo al percorso principale
pMCrv->AddLine( ptStart) ;
// eventuale copia nel percorso di ritorno
if ( pRCrv != nullptr)
pRCrv->AddCurve( *pMCrv->GetLastCurve()) ;
}
// se richiesta percorrenza invertita
if ( m_Params.m_bInvert)
pOffs->Invert() ;
// aggiungo la curva
pMCrv->AddCurve( Release( pOffs)) ;
}
// se offset va bene
if ( bNextOk) {
// sistemo per prossimo step
dCurrRad = dRad ;
pOffs.Set( pNextOffs) ;
pCurr = Get( pOffs) ;
// nuovo valore pari allo step
dOffs = GetSideStep() ;
}
// se altrimenti riducibile, provo con offset ridotto al raggio utensile
else if ( ! bSmallRad) {
// nuovo valore pari al raggio
dOffs = dTRad ;
}
// altrimenti esco
else
break ;
// incremento contatore iterazioni
++ nIter ;
}
// verifico il percorso di lavoro
if ( pMCrv->GetCurveCount() == 0) {
m_pMchMgr->SetLastError( 3010, "Error in SurfRoughing : : Toolpath not computable") ;
return false ;
}
// se necessario, approssimo archi con rette
if ( bSplitArcs && ! ApproxWithLines( pMCrv)) {
m_pMchMgr->SetLastError( 3021, "Error in SurfRoughing : Linear Approx not computable") ;
return false ;
}
// eventuale sistemazione archi
VerifyArcs( pMCrv) ;
// eventualmente compatto e inverto il percorso di ritorno
if ( pRCrv != nullptr) {
pRCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false) ;
pRCrv->Invert() ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfRoughing::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr)
+2 -9
View File
@@ -72,16 +72,9 @@ class SurfRoughing : public Machining
bool VerifyGeometry( SelData Id, int& nSubs) ;
bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ;
bool Chain( int nGrpDestId) ;
bool ProcessPath( int nPathId, int nPvId, int nClId) ;
bool AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr,
bool ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) ;
bool AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, bool bSplitArcs) ;
bool CalcZigZag( const ICurveComposite* pOffs, ICRVCOMPOPOVECTOR& vpCrvs) ;
bool AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf,
const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr,
double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) ;
bool CalcSpiral( const ICurveComposite* pCompo, bool bSplitArcs,
ICurveComposite* pMCrv, ICurveComposite* pRCrv) ;
bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;
bool AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;
bool AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;