EgtMachKernel :

- in Finitura di lama Section e Agross aggiunta gestione dei percorsi mediante curve composite, rimuovendo quella mediante PolyLines.
- in Finitura di lama Section migliorato il controllo del trim della sezione
- in Finitura di lama Section migliorati i contrilli sui link di tipo Standard ed Extended
- in Finiture di lama semplificazione del codice.
This commit is contained in:
Riccardo Elitropi
2026-08-17 11:38:08 +02:00
parent 1ff741b794
commit 947164bfcc
2 changed files with 399 additions and 159 deletions
+390 -153
View File
@@ -19,6 +19,7 @@
#include "OperationConst.h"
#include "OperUserNotesConst.h"
#include "GeoConst.h"
#include "EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EXeCmdLogOff.h"
#include "/EgtDev/Include/EXeConst.h"
#include "/EgtDev/Include/EGkCurveLine.h"
@@ -915,6 +916,15 @@ SawFinishing::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP)
return true ;
}
//----------------------------------------------------------------------------
bool
SawFinishing::AdjustArcCenterForAxesCalc( const CamData* pCamData, Point3d& ptCen) const
{
// compenso il raggio dell'utensile
ptCen += pCamData->GetCorrDir() * ( m_TParams.m_dDiam / 2) ;
return true ;
}
//----------------------------------------------------------------------------
bool
SawFinishing::VerifyGeometry( SelData Id, int& nSubs)
@@ -1390,44 +1400,52 @@ SawFinishing::CalculateStraightAcrossToolPath( int nAuxId, int nClId)
return false ;
}
// Verifico se richiesta approssimazione
bool bSplit = GetSplitArcs( vtTool) ;
// per ogni sezione
for ( int nSect = 0 ; nSect < ssize( vpSections) ; ++ nSect) {
// recupero la sezione corrente
ICurve* pCrv = vpSections[nSect] ;
if ( pCrv == nullptr || ! pCrv->IsValid())
continue ;
// Approssimo la curva con una spezzata
PolyLine PL ;
if ( ! pCrv->ApproxWithLines( LIN_TOL_MID, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL)) {
m_pMchMgr->SetLastError( 2706, "Error in SawFinishing : ApproxWithLines") ;
// Recupero la Curva Composita associata alla sezione locale
PtrOwner<ICurveComposite> pCompo( ConvertCurveToComposite( ::Release( vpSections[nSect]))) ;
if ( IsNull( pCompo) || ! pCompo->IsValid())
return false ;
// Se richiesta approssimazione
if ( bSplit) {
PolyLine PL ;
if ( ! pCompo->ApproxWithLines( LIN_TOL_MID, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL) ||
! pCompo->Clear() || ! pCompo->FromPolyLine( PL)) {
m_pMchMgr->SetLastError( 2706, "Error in SawFinishing : ApproxWithLines") ;
return false ;
}
}
else {
// Aggiungo dei Join presso gli archi nei loro punti estremi in Z e limito l'angolo massimo dell'arco
const double MAX_ANG_DEG = 45. ;
if ( ! SplitLeftRightArcSection( pCompo, MAX_ANG_DEG))
return false ;
}
// Se standard, allungo inizio e fine della sezione dello spessore lama
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_STD) {
// inizio
PL.Invert() ;
double dU ;
Point3d ptP ;
PL.GetLastUPoint( &dU, &ptP) ;
PL.AddUPoint( dU, ptP + Vector3d( m_TParams.m_dThick, 0, 0)) ;
PL.Invert() ;
// fine
PL.GetLastUPoint( &dU, &ptP) ;
PL.AddUPoint( dU, ptP - Vector3d( m_TParams.m_dThick, 0, 0)) ;
Point3d ptStart ; pCompo->GetStartPoint( ptStart) ;
pCompo->AddLine( ptStart + m_TParams.m_dThick * X_AX, false) ;
Point3d ptEnd ; pCompo->GetEndPoint( ptEnd) ;
pCompo->AddLine( ptEnd - m_TParams.m_dThick * X_AX, true) ;
}
// La porto in globale
PL.ToGlob( frSect) ;
PL.Translate( vtDeltaSect) ;
pCompo->ToGlob( frSect) ;
pCompo->Translate( vtDeltaSect) ;
if ( m_Params.m_bInvert)
PL.Translate( ptGdStart - ptGdEnd) ;
pCompo->Translate( ptGdStart - ptGdEnd) ;
// Calcolo eventuale anticipo dell'inizio
double dAddStart = 0 ;
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
BBox3d b3PL ;
PL.GetLocalBBox( b3PL) ;
pCompo->GetLocalBBox( b3PL) ;
double dMaxElev = min( dDepth, b3Raw.GetMax().z - b3PL.GetMin().z) ;
if ( dMaxElev > 0.0 && dMaxElev < 0.5 * m_TParams.m_dDiam)
dAddStart = sqrt( dMaxElev * m_TParams.m_dDiam - dMaxElev * dMaxElev) ;
@@ -1457,12 +1475,12 @@ SawFinishing::CalculateStraightAcrossToolPath( int nAuxId, int nClId)
Vector3d vtMove = vtGdDir * ( - dAddStart + i * dStep) ;
// lavoro la sezione
if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) {
if ( ! CalcAcrossOneWayCut( PL, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth))
if ( ! CalcAcrossOneWayCut( pCompo, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth))
return false ;
}
else {
bool bFirst = ( i == 0) ;
if ( ! CalcAcrossZigZagCut( PL, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth, bFirst))
if ( ! CalcAcrossZigZagCut( pCompo, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth, bFirst))
return false ;
}
}
@@ -1866,11 +1884,16 @@ SawFinishing::CalculateStraightSectionToolPath( int nAuxId, int nClId)
BBox3d b3Sect ; m_pGeomDB->GetGlobalBBox( nSectGrpId, b3Sect) ;
// Recupero ed elaboro le sezioni per portarle ad essere la curva del centro in basso della lama
ICurve* pSect ;
if ( ! CalculateOffsetSection( nSectGrpId, frSect, pSect))
ICurve* pSect,
* pOrigSect ;
ISurfFlatRegion* pSfrLimit ;
if ( ! CalculateOffsetSection( nSectGrpId, frSect, pSect, pOrigSect, pSfrLimit))
return false ;
PtrOwner<ICurve> pCrv( pSect) ;
if ( IsNull( pCrv) || ! pCrv->IsValid())
PtrOwner<ICurve> pCrv( pSect),
pCrvOrig( pOrigSect) ;
PtrOwner<ISurfFlatRegion> pSfrTabLimit( pSfrLimit) ;
if ( IsNull( pCrv) || ! pCrv->IsValid() || IsNull( pCrvOrig) || ! pCrvOrig->IsValid() ||
IsNull( pSfrTabLimit) || ! pSfrTabLimit->IsValid())
return false ;
// Recupero da UserNotes il flag di estensione al bordo del grezzo
@@ -1932,29 +1955,94 @@ SawFinishing::CalculateStraightSectionToolPath( int nAuxId, int nClId)
return false ;
}
// Approssimo la curva di sezione ad una spezzata
PolyLine PL ;
if ( ! pCrv->ApproxWithLines( LIN_TOL_MID, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL)) {
m_pMchMgr->SetLastError( 2706, "Error in SawFinishing : ApproxWithLines") ;
// Recupero la Curva Composita associata alla sezione locale
PtrOwner<ICurveComposite> pCompo( ConvertCurveToComposite( ::Release( pCrv))) ;
if ( IsNull( pCompo) || ! pCompo->IsValid())
return false ;
// Verifico se richiesta approssimazione
bool bSplit = GetSplitArcs( vtTool) ;
if ( bSplit) {
// Approssimo la curva di sezione ad una spezzata
PolyLine PL ;
if ( ! pCrv->ApproxWithLines( LIN_TOL_MID, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL) ||
! pCompo->Clear() || ! pCompo->FromPolyLine( PL)) {
m_pMchMgr->SetLastError( 2706, "Error in SawFinishing : ApproxWithLines") ;
return false ;
}
}
// Se link standard, allungo inizio e fine della sezione dello spessore lama
else {
// Aggiungo dei Join presso gli archi nei loro punti estremi in Z e limito l'angolo massimo dell'arco
const double MAX_ANG_DEG = 45. ;
if ( ! SplitLeftRightArcSection( pCompo, MAX_ANG_DEG))
return false ;
}
// Se link standard, allungo inizio e fine della sezione dello spessore lama (senza scendere sotto la quota Z di sicurezza)
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_STD) {
// inizio
PL.Invert() ;
double dU ;
Point3d ptP ;
PL.GetLastUPoint( &dU, &ptP) ;
PL.AddUPoint( dU, ptP + Vector3d( m_TParams.m_dThick, 0., 0.)) ;
PL.Invert() ;
// fine
PL.GetLastUPoint( &dU, &ptP) ;
PL.AddUPoint( dU, ptP - Vector3d( m_TParams.m_dThick, 0., 0.)) ;
Point3d ptS, ptE ;
pCompo->GetStartPoint( ptS) ; pCompo->GetEndPoint( ptE) ;
Vector3d vtS, vtE ;
pCompo->GetStartDir( vtS) ; vtS.Invert() ; pCompo->GetEndDir( vtE) ;
PtrOwner<ICurveLine> pLineS( CreateCurveLine()),
pLineE( CreateCurveLine()) ;
if ( IsNull( pLineS) || ! pLineS->Set( ptS, ptS + vtS * m_TParams.m_dThick) ||
IsNull( pLineE) || ! pLineE->Set( ptE, ptE + vtE * m_TParams.m_dThick))
return false ;
PtrOwner<ICurve> pCrvLimit( pSfrTabLimit->GetLoop( 0, 0)) ;
if ( IsNull( pCrvLimit) || ! pCrvLimit->IsValid())
return false ;
// --- aggiunta estensione iniziale (verifica con sezione e tavola)
pLineS->SetExtrusion( GetToLoc( vtTool, frSect)) ;
PtrOwner<ISurfFlatRegion> pSfrSawShape( GetSurfFlatRegionFromFatCurve( pLineS->Clone(), m_TParams.m_dDiam / 2. + GetOffsR() - 10. * EPS_SMALL, false, false)) ;
if ( IsNull( pSfrSawShape) || ! pSfrSawShape->IsValid() ||
! pSfrSawShape->Translate( GetToLoc( vtCorr, frSect) * m_TParams.m_dDiam / 2.))
return false ;
CRVCVECTOR ccClass ;
if ( ! pSfrSawShape->GetCurveClassification( *pCrvOrig, EPS_SMALL, ccClass))
return false ;
bool bInters = false ;
for ( int j = 0 ; ! bInters && j < ssize( ccClass) ; ++ j)
bInters = ( ccClass[j].nClass == CRVC_IN) ;
if ( ! bInters) {
IntersCurveCurve ICCS( *pLineS, *pCrvLimit) ;
if ( ICCS.GetIntersCount() == 0)
pCompo->AddLine( ptS + vtS * m_TParams.m_dThick, false) ;
else {
IntCrvCrvInfo aInfo ;
if ( ! ICCS.GetIntCrvCrvInfo( 0, aInfo))
return false ;
pCompo->AddLine( aInfo.IciA->ptI, false) ;
}
}
// --- aggiunta estensione finale (verifica con sezione e tavola)
pLineE->SetExtrusion( GetToLoc( vtTool, frSect)) ;
pSfrSawShape.Set( GetSurfFlatRegionFromFatCurve( pLineE->Clone(), m_TParams.m_dDiam / 2. + GetOffsR() - 10. * EPS_SMALL, false, false)) ;
if ( IsNull( pSfrSawShape) || ! pSfrSawShape->IsValid() ||
! pSfrSawShape->Translate( GetToLoc( vtCorr, frSect) * m_TParams.m_dDiam / 2.))
return false ;
ccClass.clear() ;
if ( ! pSfrSawShape->GetCurveClassification( *pCrvOrig, EPS_SMALL, ccClass))
return false ;
bInters = false ;
for ( int j = 0 ; ! bInters && j < ssize( ccClass) ; ++ j)
bInters = ( ccClass[j].nClass == CRVC_IN) ;
if ( ! bInters) {
IntersCurveCurve ICCE( *pLineE, *pCrvLimit) ;
if ( ICCE.GetIntersCount() == 0)
pCompo->AddLine( ptE + vtE * m_TParams.m_dThick, true) ;
else {
IntCrvCrvInfo aInfo ;
if ( ! ICCE.GetIntCrvCrvInfo( 0, aInfo))
return false ;
pCompo->AddLine( aInfo.IciA->ptI, true) ;
}
}
}
// La porto in globale
PL.ToGlob( frSect) ;
pCompo->ToGlob( frSect) ;
// traslo la sezione lungo la direzione della guida per farla coicidere con il suo punto iniziale
PL.Translate( ( ( ptGdStart - GetToGlob( ptSecStart, frSect)) * vtGdDir) * vtGdDir) ;
pCompo->Translate( ( ( ptGdStart - GetToGlob( ptSecStart, frSect)) * vtGdDir) * vtGdDir) ;
// Imposto dati comuni
SetPathId( nPxId) ;
@@ -2001,24 +2089,38 @@ SawFinishing::CalculateStraightSectionToolPath( int nAuxId, int nClId)
int nStep = static_cast<int>( ceil( dL/dStep)) ;
dStep = dL / nStep ;
Point3d ptP ;
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
pCrvOrig->ToGlob( frSect) ;
pSfrTabLimit->ToGlob( frSect) ;
}
for ( int i = 0 ; i <= nStep ; ++ i) {
// vettore di spostamento
Vector3d vtMove = vtGdDir * ( i * dStep) ;
// Curva di percorso corrente
ICurveComposite* pCompoPath = pCompo ;
// se link Extended, allora estendo il percorso fino alla dimensione del grezzo
PtrOwner<ICurveComposite> pCompoTmp( nullptr) ;
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
PL.Translate( vtMove) ;
if ( ! ExtendPathToRaw( PL, pStmRaw, m_TParams.m_dThick))
pCompoTmp.Set( CloneCurveComposite( pCompoPath)) ;
if ( IsNull( pCompoTmp))
return false ;
PL.Translate( - vtMove) ;
pCompoTmp->Translate( vtMove) ;
if ( ! ExtendPathToRaw( pCompoTmp, pStmRaw, m_TParams.m_dThick, pCrvOrig))
return false ;
pCompoTmp->Translate( - vtMove) ;
pCompoPath = pCompoTmp ;
}
// lavoro la sezione
if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) {
if ( ! CalcAcrossOneWayCut( PL, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth))
if ( ! CalcAcrossOneWayCut( pCompoPath, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth))
return false ;
}
else {
bool bFirst = ( i == 0) ;
if ( ! CalcAcrossZigZagCut( PL, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth, bFirst))
if ( ! CalcAcrossZigZagCut( pCompoPath, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth, bFirst))
return false ;
}
}
@@ -2153,15 +2255,18 @@ SawFinishing::CalculateStraightAlong5AToolPath( int nAuxId, int nClId)
//----------------------------------------------------------------------------
bool
SawFinishing::ExtendPathToRaw( PolyLine& PL, const ISurfTriMesh* pStmRaw, double dExtraOut) const
SawFinishing::ExtendPathToRaw( ICurveComposite* pCompo, const ISurfTriMesh* pStmRaw, double dExtraOut, const ICurve* pSection) const
{
// se grezzo non valido, non estendo nulla
if ( pStmRaw == nullptr || ! pStmRaw->IsValid() || pStmRaw->GetTriangleCount() == 0)
return true ;
// se curve non valide, errore
if ( pCompo == nullptr || ! pCompo->IsValid())
return false ;
// recupero gli estremi della PolyLine e il versore di estensione
Point3d ptS ; PL.GetFirstPoint( ptS) ;
Point3d ptE ; PL.GetLastPoint( ptE) ;
Point3d ptS ; pCompo->GetStartPoint( ptS) ;
Point3d ptE ; pCompo->GetEndPoint( ptE) ;
Vector3d vtExt = ( ptE - ptS) ;
vtExt.z = 0. ;
if ( ! vtExt.Normalize())
@@ -2178,11 +2283,32 @@ SawFinishing::ExtendPathToRaw( PolyLine& PL, const ISurfTriMesh* pStmRaw, double
for ( int i = 0 ; i < ssize( vInfo) ; ++ i) {
// se c'è intersezione ed esco dalla superficie
if ( vInfo[i].nILTT != ILTT_NO && vInfo[i].dCosDN > COS_SMALL) {
// aggiungo il punto di intersezione con il grezzo
PL.AddUPoint( 0., vInfo[i].ptI, false) ;
// verifico se la lama rovina la sezione corrente
if ( pSection != nullptr && pSection->IsValid()) {
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine))
return false ;
if ( ! pLine->Set( ptS, vInfo[i].ptI) || ! pLine->SetExtrusion( m_vtTool))
break ; // punti troppo vicini
// Offset della linea per recuperare il centro della lama
PtrOwner<ISurfFlatRegion> pSfrSawShape( GetSurfFlatRegionFromFatCurve( pLine->Clone(), m_TParams.m_dDiam / 2. + GetOffsR() - 10. * EPS_SMALL, false, false)) ;
if ( IsNull( pSfrSawShape) || ! pSfrSawShape->IsValid() ||
! pSfrSawShape->Translate( m_vtCorr * m_TParams.m_dDiam / 2.))
break ;
CRVCVECTOR ccClass ;
if ( ! pSfrSawShape->GetCurveClassification( *pSection, EPS_SMALL, ccClass))
break ;
bool bBreak = false ;
for ( int j = 0 ; ! bBreak && j < ssize( ccClass) ; ++ j)
bBreak = ( ccClass[j].nClass == CRVC_IN) ;
if ( bBreak)
break ;
}
// aggiungo il punto di intersezione con i grezzo
pCompo->AddLine( vInfo[i].ptI, false) ;
// aggiungo un punto per estensione aggiuntiva
if ( dExtraOut > EPS_SMALL)
PL.AddUPoint( 0., vInfo[i].ptI - vtExt * dExtraOut, false) ;
pCompo->AddLine( vInfo[i].ptI - vtExt * dExtraOut, false) ;
break ;
}
}
@@ -2196,11 +2322,32 @@ SawFinishing::ExtendPathToRaw( PolyLine& PL, const ISurfTriMesh* pStmRaw, double
for ( int i = 0 ; i < ssize( vInfo) ; ++ i) {
// se c'è intersezione ed esco dalla superficie
if ( vInfo[i].nILTT != ILTT_NO && vInfo[i].dCosDN > COS_SMALL) {
// verifico se la lama rovina la sezione corrente
if ( pSection != nullptr && pSection->IsValid()) {
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ;
if ( IsNull( pLine))
return false ;
if ( ! pLine->Set( ptE, vInfo[i].ptI) || ! pLine->SetExtrusion( m_vtTool))
break ; // punti troppo vicini
// Offset della linea per recuperare il centro della lama
PtrOwner<ISurfFlatRegion> pSfrSawShape( GetSurfFlatRegionFromFatCurve( pLine->Clone(), m_TParams.m_dDiam / 2. + GetOffsR() - 10. * EPS_SMALL, false, false)) ;
if ( IsNull( pSfrSawShape) || ! pSfrSawShape->IsValid() ||
! pSfrSawShape->Translate( m_vtCorr * m_TParams.m_dDiam / 2.))
break ;
CRVCVECTOR ccClass ;
if ( ! pSfrSawShape->GetCurveClassification( *pSection, EPS_SMALL, ccClass))
break ;
bool bBreak = false ;
for ( int j = 0 ; ! bBreak && j < ssize( ccClass) ; ++ j)
bBreak = ( ccClass[j].nClass == CRVC_IN) ;
if ( bBreak)
break ;
}
// aggiungo il punto di intersezione con il grezzo
PL.AddUPoint( 0., vInfo[i].ptI, true) ;
pCompo->AddLine( vInfo[i].ptI, true) ;
// aggiungo un punto per estensione aggiuntiva
if ( dExtraOut > EPS_SMALL)
PL.AddUPoint( 0., vInfo[i].ptI + vtExt * dExtraOut, true) ;
pCompo->AddLine( vInfo[i].ptI + vtExt * dExtraOut, true) ;
break ;
}
}
@@ -2211,7 +2358,8 @@ SawFinishing::ExtendPathToRaw( PolyLine& PL, const ISurfTriMesh* pStmRaw, double
//----------------------------------------------------------------------------
bool
SawFinishing::CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICurve*& pSect) const
SawFinishing::CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICurve*& pSect, ICurve*& pOrigSec,
ISurfFlatRegion*& pSfrLimit) const
{
// recupero le sezioni
ICURVEPVECTOR vpSects ;
@@ -2239,8 +2387,7 @@ SawFinishing::CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICur
// calcolo ordinamento delle curve secondo la X decrescente
typedef pair<int,double> INDASC ; // coppia indice, ascissa
typedef vector<INDASC> INDASCVECTOR ; // vettore di coppie indice, ascissa
INDASCVECTOR vIAsc ;
vIAsc.reserve( vpNucCrvs.size()) ;
INDASCVECTOR vIAsc ; vIAsc.reserve( vpNucCrvs.size()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
Point3d ptStart ;
if ( ! vpNucCrvs[i]->GetStartPoint( ptStart))
@@ -2250,21 +2397,23 @@ SawFinishing::CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICur
sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) { return a.second > b.second ; }) ;
// definisco la regione non oltrepassabile dal fondo della lama
BBox3d b3Raw ;
if ( ! GetCurrRawsGlobBox( b3Raw) || b3Raw.IsEmpty()) {
m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Empty RawBox") ;
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr)
return false ;
}
b3Raw.ToLoc( frSec) ;
Point3d ptMin = b3Raw.GetMin(),
ptMax = b3Raw.GetMax() ;
double dMinY = 5. ;
double dTabDist = 0. ;
BBox3d BBoxLimit ;
pMch->GetCurrTableArea1( BBoxLimit) ;
if ( BBoxLimit.IsEmpty())
return false ;
BBoxLimit.ToLoc( frSec) ;
Point3d ptMin = BBoxLimit.GetMin(),
ptMax = BBoxLimit.GetMax() ;
double dMinY = 5.,
dTabDist = 0. ;
if ( GetValInNotes( m_Params.m_sUserNotes, UN_RB_DIST, dTabDist) && dTabDist > dMinY)
dMinY = dTabDist ;
const double LINE_EXT = 1e5 ;
Point3d ptLineMinYStart = Point3d( ptMin.x - LINE_EXT, ptMin.y + dMinY, 0.) ;
Point3d ptLineMinYEnd = Point3d( ptMax.x + LINE_EXT, ptMin.y + dMinY, 0.) ;
Point3d ptLineMinYStart = Point3d( ptMin.x - LINE_EXT, ptMax.y + dMinY, 0.),
ptLineMinYEnd = Point3d( ptMax.x + LINE_EXT, ptMax.y + dMinY, 0.) ;
PtrOwner<ICurveComposite> pCompoRegLimit( CreateCurveComposite()) ;
if ( IsNull( pCompoRegLimit))
return false ;
@@ -2273,10 +2422,12 @@ SawFinishing::CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICur
pCompoRegLimit->AddLine( ptLineMinYEnd - Y_AX * LINE_EXT) ;
pCompoRegLimit->AddLine( ptLineMinYEnd) ;
pCompoRegLimit->Close() ;
PtrOwner<ISurfFlatRegion> pSfrLimit( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrLimit) || ! pSfrLimit->AddExtLoop( ::Release( pCompoRegLimit)))
PtrOwner<ISurfFlatRegion> pMySfrLimit( CreateSurfFlatRegion()) ;
if ( IsNull( pMySfrLimit) || ! pMySfrLimit->AddExtLoop( ::Release( pCompoRegLimit)))
return false ;
pSfrLimit = Release( pMySfrLimit) ;
// unisco le diverse curve (ora aperte) in un unico profilo
PtrOwner<ICurveComposite> pCurve( CreateCurveComposite()) ;
if ( IsNull( pCurve))
@@ -2294,11 +2445,22 @@ SawFinishing::CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICur
bFirst = false ;
}
// memorizzo la sezione corrente
if ( IsNull( pCurve) || ! pCurve->IsValid())
return false ;
pOrigSec = pCurve->Clone() ;
// effettuo trim per parti iniziali e finali
if ( ! TrimSection( pCurve))
return false ;
// offset radiale delle sezioni per il sovramateriale e il raggio utensile
OffsetCurve OffsCrv ;
pCurve->Translate( - Y_AX * m_TParams.m_dDiam / 2.) ;
OffsCrv.Make( pCurve, m_TParams.m_dDiam / 2. + GetOffsR(), ICurve::OFF_FILLET) ;
PtrOwner<ICurve> pOvrCrv( OffsCrv.GetLongerCurve()) ;
if ( IsNull( pOvrCrv))
return false ;
// la curva ricavata deve essere sufficientemente distante dal fondo del grezzo
CRVCVECTOR ccClass ;
@@ -2326,7 +2488,7 @@ SawFinishing::CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICur
}
// eseguo trim (se richiesto)
if ( IsNull( pCurve) || ! TrimSection( pCurve))
if ( IsNull( pCurve))
return false ;
pSect = Release( pCurve) ;
@@ -2731,6 +2893,57 @@ SawFinishing::Split5ASection( int nSectGrpId, SECTIONVECTOR& vSections) const
return true ;
}
//----------------------------------------------------------------------------
bool
SawFinishing::SplitLeftRightArcSection( ICurveComposite* pCompo, double dMaxAngDeg) const
{
// verifico che la curva composita sia valida
if ( pCompo == nullptr || ! pCompo->IsValid())
return false ;
// verifico valore dell'angolo
double dMyMaxAngDeg = Clamp( dMaxAngDeg, 15., 90.) ;
int i = 0 ;
const ICurve* pCrv = pCompo->GetCurve( i) ;
while ( pCrv != nullptr) {
if ( pCrv->GetType() == CRV_ARC) {
const ICurveArc* pArc = GetCurveArc( pCrv) ;
// determino la rotazione angolare dall'inizio alle direzioni su e giù
double dAng1, dAng2 ;
bool bDet ;
pArc->GetStartVersor().GetRotation( Y_AX, Z_AX, dAng1, bDet) ;
pArc->GetStartVersor().GetRotation( - Y_AX, Z_AX, dAng2, bDet) ;
// oriento queste rotazioni come l'angolo al centro dell'arco
if ( pArc->GetAngCenter() > 0.) {
if ( dAng1 < 0.)
dAng1 += ANG_FULL ;
if ( dAng2 < 0.)
dAng2 += ANG_FULL ;
}
else {
if ( dAng1 > 0.)
dAng1 -= ANG_FULL ;
if ( dAng2 > 0.)
dAng2 -= ANG_FULL ;
}
// le ordino in senso crescente di ampiezza assoluta
if ( abs( dAng1) > abs( dAng2))
swap( dAng1, dAng2) ;
// verifico se la prima di queste rotazioni è compresa nell'arco
if ( abs( dAng1) > EPS_ANG_SMALL && abs( dAng1) < abs( pArc->GetAngCenter()) - EPS_ANG_SMALL)
pCompo->AddJoint( i + dAng1 / pArc->GetAngCenter()) ;
// verifico la seconda
else if ( abs( dAng2) > EPS_ANG_SMALL && abs( dAng2) < abs( pArc->GetAngCenter()) - EPS_ANG_SMALL)
pCompo->AddJoint( i + dAng2 / pArc->GetAngCenter()) ;
}
// passo alla successiva
pCrv = pCompo->GetCurve( ++ i) ;
}
// verifiche sull'ampiezza dell'angolo al centro degli eventuali archi
return VerifyArcs( pCompo, dMyMaxAngDeg) ;
}
//----------------------------------------------------------------------------
bool
SawFinishing::AdaptGuideLineToRaw( Point3d& ptGdStart, Point3d& ptGdEnd, const Vector3d& vtGdDir, bool bExtend, const ISurfTriMesh* pStmRaw) const
@@ -3678,55 +3891,67 @@ SawFinishing::CalcAlongZigZagCut( const Point3d& ptStart, const Point3d& ptEnd,
//----------------------------------------------------------------------------
bool
SawFinishing::CalcAcrossOneWayCut( const PolyLine& PL, const Vector3d& vtMove,
const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth)
SawFinishing::CalcAcrossOneWayCut( const ICurveComposite* pCompo, const Vector3d& vtMove,
const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth)
{
// verifico che la curva sia valida
if ( pCompo == nullptr || ! pCompo->IsValid())
return false ;
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
Point3d ptP ;
// 1 -> approccio
bool bFound = PL.GetFirstPoint( ptP) ;
if ( bFound) {
ptP += vtMove - 0.5 * m_TParams.m_dThick * vtTool ;
ptP.z = max( ptP.z, dRawZ - dDepth) ;
double dElev = dRawZ - ptP.z ;
if ( ! AddApproach( ptP, vtCorr, dSafeZ, dElev, dAppr))
Point3d ptPrev ; GetCurrPos( ptPrev) ;
// ciclo sulle curve della sezione
int nCrvCnt = pCompo->GetCurveCount() ;
for ( int i = 0 ; i < nCrvCnt ; ++ i) {
// recupero la curva corrente
const ICurve* pCrv = pCompo->GetCurve( i) ;
if ( pCrv == nullptr || ! pCrv->IsValid())
return false ;
}
// 2 -> movimento lungo la sezione
Point3d ptPrev ;
GetCurrPos( ptPrev) ;
while ( bFound) {
// se diverso da precedente, movimento al punto
if ( ! AreSamePointEpsilon( ptP, ptPrev, 10 * EPS_SMALL)) {
Vector3d vtDelta = ptP - ptPrev ;
if ( vtDelta.z > - EPS_SMALL)
SetFeed( GetFeed()) ;
else {
double dC = sqrt( 1 + ( vtDelta.x * vtDelta.x + vtDelta.y * vtDelta.y) / ( vtDelta.z * vtDelta.z)) ;
double dF = min( GetFeed(), dC * GetTipFeed()) ;
SetFeed( dF) ;
}
if ( AddLinearMove( ptP) == GDB_ID_NULL)
return false ;
ptPrev = ptP ;
}
// recupero punto successivo
bFound = PL.GetNextPoint( ptP) ;
if ( bFound) {
ptP += vtMove - 0.5 * m_TParams.m_dThick * vtTool ;
// sposto la curva corrente
PtrOwner<ICurve> pMyCrv( pCrv->Clone()) ;
if ( IsNull( pMyCrv) || ! pMyCrv->Translate( vtMove - 0.5 * m_TParams.m_dThick * vtTool))
return false ;
// approccio
if ( i == 0) {
Point3d ptP ; pMyCrv->GetStartPoint( ptP) ;
ptP.z = max( ptP.z, dRawZ - dDepth) ;
double dElev = dRawZ - ptP.z ;
if ( ! AddApproach( ptP, vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
// aggiungo la curva corrente
Point3d ptP ; pMyCrv->GetStartPoint( ptP) ;
Vector3d vtDelta = ptP - ptPrev ;
if ( vtDelta.z > - EPS_SMALL)
SetFeed( GetFeed()) ;
else {
double dC = sqrt( 1 + ( vtDelta.x * vtDelta.x + vtDelta.y * vtDelta.y) / ( vtDelta.z * vtDelta.z)) ;
double dF = min( GetFeed(), dC * GetTipFeed()) ;
SetFeed( dF) ;
}
// -- se derivo da approccio, collegamento lineare all'inizio della curva
if ( i == 0)
AddLinearMove( ptP) ;
if ( AddCurveMove( pMyCrv) == GDB_ID_NULL)
return false ;
ptPrev = ptP ;
// retroazione
if ( i == nCrvCnt - 1) {
Point3d ptP ; pMyCrv->GetEndPoint( ptP) ;
double dElev = dRawZ - ptP.z ;
if ( ! AddRetract( ptP, vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
}
// 3-> retrazione
{
double dElev = dRawZ - ptP.z ;
if ( ! AddRetract( ptP, vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
// incremento contatore passate
++ m_nCuts ;
@@ -3735,54 +3960,66 @@ SawFinishing::CalcAcrossOneWayCut( const PolyLine& PL, const Vector3d& vtMove,
//----------------------------------------------------------------------------
bool
SawFinishing::CalcAcrossZigZagCut( const PolyLine& PL, const Vector3d& vtMove,
const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth, bool bFirst)
SawFinishing::CalcAcrossZigZagCut( const ICurveComposite* pCompo, const Vector3d& vtMove,
const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth, bool bFirst)
{
// verifico che la curva sia valida
if ( pCompo == nullptr || ! pCompo->IsValid())
return false ;
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
// sezione da invertire
bool bInvert = (( m_nCuts % 2) != 0) ;
Point3d ptPrev ; GetCurrPos( ptPrev) ;
Point3d ptP ;
bool bFound = ( bInvert ? PL.GetLastPoint( ptP) : PL.GetFirstPoint( ptP)) ;
// 1 -> approccio
if ( bFound) {
ptP += vtMove - 0.5 * m_TParams.m_dThick * vtTool ;
ptP.z = max( ptP.z, dRawZ - dDepth) ;
if ( bFirst) {
double dElev = dRawZ - ptP.z ;
if ( ! AddApproach( ptP, vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
}
// 2 -> movimento lungo la sezione
Point3d ptPrev ;
GetCurrPos( ptPrev) ;
while ( bFound) {
// se diverso da precedente, movimento al punto
if ( ! AreSamePointEpsilon( ptP, ptPrev, 10 * EPS_SMALL)) {
Vector3d vtDelta = ptP - ptPrev ;
if ( vtDelta.z > - EPS_SMALL)
SetFeed( GetFeed()) ;
else {
double dC = sqrt( 1 + ( vtDelta.x * vtDelta.x + vtDelta.y * vtDelta.y) / ( vtDelta.z * vtDelta.z)) ;
double dF = min( GetFeed(), dC * GetTipFeed()) ;
SetFeed( dF) ;
}
if ( AddLinearMove( ptP) == GDB_ID_NULL)
return false ;
ptPrev = ptP ;
}
// recupero punto successivo
bFound = ( bInvert ? PL.GetPrevPoint( ptP) : PL.GetNextPoint( ptP)) ;
if ( bFound) {
ptP += vtMove - 0.5 * m_TParams.m_dThick * vtTool ;
// ciclo sulle curve della sezione
bool bInvert = ( ! IsEven( m_nCuts)) ;
int nCrvCnt = pCompo->GetCurveCount() ;
for ( int i = ( ! bInvert ? 0 : nCrvCnt - 1) ; ( ! bInvert ? i < nCrvCnt : i >= 0) ; ( ! bInvert ? ++ i : -- i)) {
// recupero la curva corrente
const ICurve* pCrv = pCompo->GetCurve( i) ;
if ( pCrv == nullptr || ! pCrv->IsValid())
return false ;
// sposto la curva corrente
PtrOwner<ICurve> pMyCrv( pCrv->Clone()) ;
if ( IsNull( pMyCrv) || ! pMyCrv->Translate( vtMove - 0.5 * m_TParams.m_dThick * vtTool))
return false ;
if ( bInvert)
pMyCrv->Invert() ;
// approccio
bool bIsFirstIter = ( ! bInvert ? ( i == 0) : ( i == nCrvCnt - 1)) ;
if ( bIsFirstIter) {
Point3d ptP ; pMyCrv->GetStartPoint( ptP) ;
ptP.z = max( ptP.z, dRawZ - dDepth) ;
if ( bFirst) {
double dElev = dRawZ - ptP.z ;
if ( ! AddApproach( ptP, vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
}
// aggiungo la curva corrente
Point3d ptP ; pMyCrv->GetStartPoint( ptP) ;
Vector3d vtDelta = ptP - ptPrev ;
if ( vtDelta.z > - EPS_SMALL)
SetFeed( GetFeed()) ;
else {
double dC = sqrt( 1 + ( vtDelta.x * vtDelta.x + vtDelta.y * vtDelta.y) / ( vtDelta.z * vtDelta.z)) ;
double dF = min( GetFeed(), dC * GetTipFeed()) ;
SetFeed( dF) ;
}
// -- se derivo da approccio, collegamento lineare all'inizio della curva
if ( bIsFirstIter)
AddLinearMove( ptP) ;
if ( AddCurveMove( pMyCrv) == GDB_ID_NULL)
return false ;
ptPrev = ptP ;
}
// incremento contatore passate
++ m_nCuts ;
+9 -6
View File
@@ -22,6 +22,7 @@ class ICurve ;
class ICurveLine ;
class ICurveArc ;
class ICurveComposite ;
class ISurfFlatRegion ;
class ISurfTriMesh ;
class Polygon3d ;
@@ -71,6 +72,7 @@ class SawFinishing : public Machining
int GetSolCh( void) const override
{ return m_Params.m_nSolCh ; }
bool AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) const override ;
bool AdjustArcCenterForAxesCalc( const CamData* pCamData, Point3d& ptCen) const override ;
public : // Machining
bool Prepare( const std::string& sSawName) override ;
@@ -103,12 +105,13 @@ class SawFinishing : public Machining
bool CalculateCurvedAcrossToolPath( int nAuxId, int nClId) ;
bool CalculateStraightSectionToolPath( int nAuxId, int nClId) ;
bool CalculateStraightAlong5AToolPath( int nAuxId, int nClId) ;
bool CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICurve*& pSect) const ;
bool CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICurve*& pSect, ICurve*& pOrigSec, ISurfFlatRegion*& pSfrLimit) const ;
bool CalculateSection( int nSectGrpId, std::vector<PtrOwner<ICurveComposite>>& vpSections) const ;
bool TrimSection( ICurve* pCrv) const ;
bool Split5ASection( int nSectGrpId, SECTIONVECTOR& vSubSections) const ;
bool SplitLeftRightArcSection( ICurveComposite* pCompo, double dMaxAngDeg) const ;
bool AdaptGuideLineToRaw( Point3d& ptGdStart, Point3d& ptGdEnd, const Vector3d& vtGdDir, bool bExtend, const ISurfTriMesh* pStmRaw) const ;
bool ExtendPathToRaw( PolyLine& PL, const ISurfTriMesh* pStmRaw, double dExtraOut) const ;
bool ExtendPathToRaw( ICurveComposite* pCompo, const ISurfTriMesh* pStmRaw, double dExtraOutconst, const ICurve* pSection = nullptr) const ;
bool CalculateSectElevation( const Polygon3d& pgFacet, double& dElev) const ;
bool CalculateGuideLine( int nGuideId, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir,
int nSectGrpId, bool bExtendToRawBox) const ;
@@ -128,10 +131,10 @@ class SawFinishing : public Machining
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bExtend, bool bVert) ;
bool CalcAlongZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, const Vector3d& vtTool,
const Vector3d& vtCorr, double dElev, bool bExtend, bool bVert, bool bFirst, bool bAppr = false) ;
bool CalcAcrossOneWayCut( const PolyLine& PL, const Vector3d& vtMove,
const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth) ;
bool CalcAcrossZigZagCut( const PolyLine& PL, const Vector3d& vtMove,
const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth, bool bFirst) ;
bool CalcAcrossOneWayCut( const ICurveComposite* pCompo, const Vector3d& vtMove,
const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth) ;
bool CalcAcrossZigZagCut( const ICurveComposite* pCompo, const Vector3d& vtMove,
const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth, bool bFirst) ;
bool CalcCurvedAlongVerticalCuts( ICurve* pSect, int nUmin, int nUmax, const Frame3d& frSect,
ICurve* pGuide, double dDepth, double dRaxMaxZ, const Vector3d& vtTool) ;
bool CalcCurvedAlongStdCuts( ICurve* pSect, double dUmin, double dUmax,