EgtMachKernel :

- in SawFinishing aggiunto sottotipo "Section"
- in SawFinishing correzioni varie.
This commit is contained in:
Riccardo Elitropi
2026-07-07 11:37:29 +02:00
parent 0fef1fbbf9
commit 06180175eb
3 changed files with 548 additions and 21 deletions
+2
View File
@@ -65,6 +65,8 @@ static const std::string UN_EWE = "EWE" ;
// Solo per SawFinishing e SawRoughing
static const std::string UN_EXTEND = "Extend" ;
static const std::string UN_RB_DIST = "RawBottomDist" ; // per SawFinishing Section
static const std::string UN_LIMIT_ANG = "LimitAngle" ; // per SawFinishing Section
// Solo per SurfFinishing
static const std::string UN_SKIPMAXDOWN = "SkipMaxDown" ;
+539 -17
View File
@@ -58,10 +58,12 @@ using namespace std ;
// 2714 = "Error in SawFinishing : link outstroke xx"
// 2715 = "Error in SawFinishing : post apply not calculable"
// 2716 = "Error in SawFinishing : special apply not calculable"
// 2717 = "Error in SawFinishing : CalculateSectionToolPath failed"
// 2751 = "Warning in SawFinishing : Skipped entity (xx)"
// 2752 = "Warning in SawFinishing : No machinable path"
// 2753 = "Warning in SawFinishing : Tool name changed (xx)"
// 2754 = "Warning in SawFinishing : Tool data changed (xx)"
// 2755 = "Warning in SawFinishing : Link not compatible with extension"
//----------------------------------------------------------------------------
const string MCH_SECTION = "Sect" ;
@@ -588,6 +590,12 @@ SawFinishing::Apply( bool bRecalc, bool bPostApply)
}
}
}
else if ( m_Params.m_nSubType == SAWFIN_SUB_SECTION) {
if ( ! CalculateStraightSectionToolPath( nAuxId, nClId)) {
m_pMchMgr->SetLastError( 2717, "Error in SawFinishing : CalculateSectionToolPath failed") ;
return false ;
}
}
// assegno ingombri dei vari percorsi di lavorazione e della lavorazione nel suo complesso
CalcAndSetBBox( nClId) ;
@@ -1082,6 +1090,11 @@ SawFinishing::CalculateStraightAlongToolPath( int nAuxId, int nClId)
bool bExtend ;
if ( ! GetValInNotes( m_Params.m_sUserNotes, UN_EXTEND, bExtend))
bExtend = true ;
// se estensione non presente e Link di tipo Extended, lo forzo come Center
if ( ! bExtend && m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
m_pMchMgr->SetWarning( 2655, "Warning in SawRoughing : Link not compatible with extension") ;
m_Params.m_nLeadLinkType = SAWFIN_LL_CENT ;
}
// Recupero ed elaboro la linea guida
Point3d ptGdStart, ptGdEnd ;
@@ -1272,6 +1285,11 @@ SawFinishing::CalculateStraightAcrossToolPath( int nAuxId, int nClId)
bool bExtend ;
if ( ! GetValInNotes( m_Params.m_sUserNotes, UN_EXTEND, bExtend))
bExtend = true ;
// se estensione non presente e Link di tipo Extended, lo forzo come Center
if ( ! bExtend && m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
m_pMchMgr->SetWarning( 2655, "Warning in SawRoughing : Link not compatible with extension") ;
m_Params.m_nLeadLinkType = SAWFIN_LL_CENT ;
}
// Recupero ed elaboro la linea guida
Point3d ptGdStart, ptGdEnd ;
@@ -1763,7 +1781,507 @@ SawFinishing::CalculateCurvedAcrossToolPath( int nAuxId, int nClId)
//----------------------------------------------------------------------------
bool
SawFinishing::CalculateSection( int nSectGrpId, ICurve*& pSect)
SawFinishing::CalculateStraightSectionToolPath( int nAuxId, int nClId)
{
// recupero il riferimento globale delle sezioni
int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ;
Frame3d frSect ; m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ;
// recupero il box globale delle sezioni
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))
return false ;
PtrOwner<ICurve> pCrv( pSect) ;
if ( IsNull( pCrv) || ! pCrv->IsValid())
return false ;
// Recupero da UserNotes il flag di estensione al bordo del grezzo
bool bExtend ;
if ( ! GetValInNotes( m_Params.m_sUserNotes, UN_EXTEND, bExtend))
bExtend = true ;
// se estensione non presente e Link di tipo Extended, lo forzo come Center
if ( ! bExtend && m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
m_pMchMgr->SetWarning( 2655, "Warning in SawRoughing : Link not compatible with extension") ;
m_Params.m_nLeadLinkType = SAWFIN_LL_CENT ;
}
// Recupero ed elaboro la linea guida
Point3d ptGdStart, ptGdEnd ;
Vector3d vtGdDir ;
int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ;
if ( ! CalculateGuideLine( nGuideId, pSect, ptGdStart, ptGdEnd, vtGdDir, nSectGrpId, bExtend))
return false ;
if ( m_Params.m_bInvert) {
swap( ptGdStart, ptGdEnd) ;
vtGdDir.Invert() ;
}
// recupero il box globale della linea guida
BBox3d b3Guide ; m_pGeomDB->GetGlobalBBox( nGuideId, b3Guide) ;
// recupero il box del grezzo in globale
BBox3d b3Test ;
b3Test.Add( b3Sect) ;
b3Test.Add( b3Guide) ;
BBox3d b3Raw ;
if ( ! GetRawGlobBox( m_nPhase, b3Test, 10. * EPS_SMALL, b3Raw) || b3Raw.IsEmpty()) {
m_pMchMgr->SetLastError( 2703, "Error in SawFinishing : Empty RawBox") ;
return false ;
}
// valuto l'espressione dell'affondamento
ExeLuaSetGlobNumVar( "TH", 0.) ;
ExeLuaSetGlobNumVar( "RB", b3Raw.GetMax().z - b3Raw.GetMin().z) ;
double dDepth ;
if ( ! ExeLuaEvalNumExpr( m_Params.m_sDepth, &dDepth)) {
m_pMchMgr->SetLastError( 2704, "Error in SawFinishing : Depth not computable") ;
return false ;
}
// creo gruppo per geometria di lavorazione
int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ;
if ( nPxId == GDB_ID_NULL)
return false ;
m_pGeomDB->SetName( nPxId, MCH_PATH + "1_1") ;
m_pGeomDB->SetMaterial( nPxId, GREEN) ;
// Determino versori fresa e correzione
Point3d ptSecStart ; pSect->GetStartPoint( ptSecStart) ;
Point3d ptSecEnd ; pSect->GetEndPoint( ptSecEnd) ;
Vector3d vtTool, vtCorr ;
if ( ! CalculateToolAndCorrVersors( GetToGlob( ptSecEnd - ptSecStart, frSect), m_Params.m_nHeadSide, vtTool, vtCorr)) {
m_pMchMgr->SetLastError( 2705, "Error in SawFinishing : CalculateToolAndCorrVersors") ;
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") ;
return false ;
}
// Se link 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.)) ;
}
// La porto in globale
PL.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) ;
// Imposto dati comuni
SetPathId( nPxId) ;
SetToolDir( vtTool) ;
SetCorrAuxDir( vtCorr) ;
// assegno il vettore estrazione al gruppo del percorso
m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ;
// recupero la TriMesh del grezzo in globale
PtrOwner<ISurfTriMesh> pStmRaw( CreateSurfTriMesh()) ;
if ( IsNull( pStmRaw))
return false ;
pStmRaw->AdjustTopology() ;
int nRawId = m_pMchMgr->GetFirstRawPart() ;
while ( nRawId != GDB_ID_NULL) {
// verifico che il grezzo compaia nella fase
if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) {
// recupero l'oggetto dal database con tale Id
int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( nRawSolidId) ;
if ( pGObj != nullptr) {
// recupero il frame in cui si trova
Frame3d frRaw ;
m_pGeomDB->GetGlobFrame( nRawSolidId, frRaw) ;
// controllo che sia una Trimesh
if ( pGObj->GetType() == SRF_TRIMESH) {
SurfLocal StmRawPart( GetSurfTriMesh( pGObj), frRaw, GLOB_FRM) ;
// lo aggiungo alla Trimesh complessiva
pStmRaw->Add( *GetSurfTriMesh( StmRawPart)) ;
}
}
}
// passo al grezzo successivo
nRawId = m_pMchMgr->GetNextRawPart( nRawId) ;
}
// Inizializzo contatore tagli
m_nCuts = 0 ;
// Calcolo le passate
double dStep = max( m_Params.m_dSideStep, 10. * EPS_SMALL) ;
double dL = Dist( ptGdStart, ptGdEnd) ;
int nStep = static_cast<int>( ceil( dL/dStep)) ;
dStep = dL / nStep ;
Point3d ptP ;
for ( int i = 0 ; i <= nStep ; ++ i) {
// vettore di spostamento
Vector3d vtMove = vtGdDir * ( i * dStep) ;
// se link Extended, allora estendo il percorso fino alla dimensione del grezzo
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) {
PL.Translate( vtMove) ;
if ( ! ExtendPathToRaw( PL, pStmRaw, m_TParams.m_dThick))
return false ;
PL.Translate( - vtMove) ;
}
// lavoro la sezione
if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) {
if ( ! CalcAcrossOneWayCut( PL, 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))
return false ;
}
}
// se ZigZag aggiungo risalita
if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG) {
// recupero distanza di sicurezza
double dSafeZ = GetSafeZ() ;
// lunghezza di approccio/retrazione
double dAppr = m_Params.m_dStartPos ;
// aggiungo retrazione
Point3d ptEnd ;
if ( ! GetCurrPos( ptEnd))
return false ;
double dElev = b3Raw.GetMax().z - ptEnd.z ;
if ( ! AddRetract( ptEnd, vtCorr, dSafeZ, dElev, dAppr))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SawFinishing::ExtendPathToRaw( PolyLine& PL, const ISurfTriMesh* pStmRaw, double dExtraOut) const
{
// se grezzo non valido, non estendo nulla
if ( pStmRaw == nullptr || ! pStmRaw->IsValid() || pStmRaw->GetTriangleCount() == 0)
return true ;
// recupero gli estremi della PolyLine e il versore di estensione
Point3d ptS ; PL.GetFirstPoint( ptS) ;
Point3d ptE ; PL.GetLastPoint( ptE) ;
Vector3d vtExt = ( ptE - ptS) ;
vtExt.z = 0. ;
if ( ! vtExt.Normalize())
return false ;
const double LINE_LEN = 1e5 ;
const double COS_SMALL = sin( EPS_ANG_SMALL * DEGTORAD) ;
// verifico se posso estendere l'inizio
ILSIVECTOR vInfo ;
if ( ! IntersLineSurfTm( ptS, - vtExt, LINE_LEN, *pStmRaw, vInfo))
return false ;
if ( ! vInfo.empty()) {
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) ;
// aggiungo un punto per estensione aggiuntiva
if ( dExtraOut > EPS_SMALL)
PL.AddUPoint( 0., vInfo[i].ptI - vtExt * dExtraOut, false) ;
break ;
}
}
}
// allo stesso modo, verifico se posso estendere la fine
vInfo.clear() ;
if ( ! IntersLineSurfTm( ptE, vtExt, LINE_LEN, *pStmRaw, vInfo))
return false ;
if ( ! vInfo.empty()) {
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, true) ;
// aggiungo un punto per estensione aggiuntiva
if ( dExtraOut > EPS_SMALL)
PL.AddUPoint( 0., vInfo[i].ptI + vtExt * dExtraOut, true) ;
break ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
SawFinishing::TrimVerticalSectionBounds( ICurveComposite* pSect, double dAngDeg) const
{
// verifico che la curva sia valida
if ( pSect == nullptr || ! pSect->IsValid())
return false ;
// -->! NB. La sezione è già orientata per X decrescente e nel piano XY
// splitto gli archi con angolo maggiore della tolleranza
VerifyArcs( pSect, dAngDeg) ;
// elimino tutti i tratti all'inizio della sezione
const double COS_ANG_TOL = cos( ( dAngDeg) * DEGTORAD) ;
for ( int i = 0 ; i < pSect->GetCurveCount() ; ++ i) {
const ICurve* pCrv = pSect->GetCurve( i) ;
if ( pCrv != nullptr && pCrv->IsValid()) {
// se Linea
if ( pCrv->GetType() == CRV_LINE) {
Vector3d vtDir ; pCrv->GetStartDir( vtDir) ;
Vector3d vtPerp = vtDir ; vtPerp.Rotate( Z_AX, - ANG_RIGHT) ;
if ( abs( vtPerp * Y_AX) > COS_ANG_TOL) {
// se prima linea in tolleranza, elimino tutte le curve precedenti
if ( i > 0)
pSect->TrimStartAtParam( 1. * i) ;
break ;
}
}
// se Arco
else if ( pCrv->GetType() == CRV_ARC) {
const ICurveArc* pArc = GetCurveArc( pCrv) ;
if ( pArc == nullptr)
return false ;
Point3d ptCenter = pArc->GetCenter() ;
Point3d ptStart ; pArc->GetStartPoint( ptStart) ;
Point3d ptEnd ; pArc->GetEndPoint( ptEnd) ;
Vector3d vtDirS = ( ptStart - ptCenter) ; vtDirS.Normalize() ;
Vector3d vtDirE = ( ptEnd - ptCenter) ; vtDirE.Normalize() ;
bool bOkStart = ( abs( vtDirS * Y_AX) > COS_ANG_TOL) ;
bool bOkEnd = ( abs( vtDirE * Y_AX) > COS_ANG_TOL) ;
// se inizio valido, allora non ho bisogno di modificare l'arco corrente (elimino eventuali curve precedenti)
if ( bOkStart) {
if ( i > 0)
pSect->TrimStartAtParam( 1. * i) ;
break ;
}
// se nè inizio nè fine validi, passo il controllo alla curva successiva
if ( ! bOkEnd)
continue ;
// se inizio non valido, ma fine in tolleranza, determino il nuovo punto iniziale della curva e trimmo tutto in precedenza
else {
// Trim iniziale
Point3d ptNewStart = ptCenter + pArc->GetRadius() * Y_AX ;
ptNewStart.Rotate( ptCenter, Z_AX, - dAngDeg) ;
double dUTrim = 0. ;
pSect->GetParamAtPoint( ptNewStart, dUTrim, 10. * EPS_SMALL) ;
pSect->TrimStartAtParam( dUTrim) ;
break ;
}
}
}
}
// ripeto lo stesso ragionemento per il tratto finale
if ( ! pSect->IsValid())
return false ;
for ( int i = pSect->GetCurveCount() - 1 ; i >= 0 ; -- i) {
const ICurve* pCrv = pSect->GetCurve( i) ;
if ( pCrv != nullptr && pCrv->IsValid()) {
// se Linea
if ( pCrv->GetType() == CRV_LINE) {
Vector3d vtDir ; pCrv->GetStartDir( vtDir) ;
Vector3d vtPerp = vtDir ; vtPerp.Rotate( Z_AX, - ANG_RIGHT) ;
if ( abs( vtPerp * Y_AX) > COS_ANG_TOL) {
// se linea in tolleranza, elimino tutte le successive
if ( i < pSect->GetCurveCount() - 1)
pSect->TrimEndAtParam( 1. * ( i + 1)) ;
break ;
}
}
// se Arco
else if ( pCrv->GetType() == CRV_ARC) {
const ICurveArc* pArc = GetCurveArc( pCrv) ;
if ( pArc == nullptr)
return false ;
Point3d ptCenter = pArc->GetCenter() ;
Point3d ptStart ; pArc->GetStartPoint( ptStart) ;
Point3d ptEnd ; pArc->GetEndPoint( ptEnd) ;
Vector3d vtDirS = ( ptStart - ptCenter) ; vtDirS.Normalize() ;
Vector3d vtDirE = ( ptEnd - ptCenter) ; vtDirE.Normalize() ;
bool bOkStart = ( abs( vtDirS * Y_AX) > COS_ANG_TOL) ;
bool bOkEnd = ( abs( vtDirE * Y_AX) > COS_ANG_TOL) ;
// se fine valido, non ho bisogno di modificare l'arco corrente (elimino eventuali curve precedenti)
if ( bOkEnd) {
if ( i < pSect->GetCurveCount() - 1)
pSect->TrimEndAtParam( 1. * ( i + 1)) ;
break ;
}
// se nè inizio nè fine validi, passo il controllo alla curva successiva
if ( ! bOkStart)
continue ;
// se inizio no valido, ma fine in tolleranza, determino il nuovo punto finale della curva e trimmo tutto in successione
else {
// Trim Finale
Point3d ptNewEnd = ptCenter + pArc->GetRadius() * Y_AX ;
ptNewEnd.Rotate( ptCenter, Z_AX, dAngDeg) ;
double dUTrim = pSect->GetCurveCount() - 1 ;
pSect->GetParamAtPoint( ptNewEnd, dUTrim, 10. * EPS_SMALL) ;
pSect->TrimEndAtParam( dUTrim) ;
break ;
}
}
}
}
if ( pSect->IsValid()) {
pSect->MergeCurves( LIN_TOL_MID, ANG_TOL_STD_DEG) ;
return true ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
SawFinishing::CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICurve*& pSect) const
{
// recupero le sezioni
ICURVEPVECTOR vpSects ;
int nSectId = m_pGeomDB->GetFirstInGroup( nSectGrpId) ;
while ( nSectId != GDB_ID_NULL) {
// recupero il puntatore alla curva
vpSects.emplace_back( ::GetCurve( m_pGeomDB->GetGeoObj( nSectId))) ;
if ( vpSects.back() == nullptr)
return false ;
// passo alla successiva
nSectId = m_pGeomDB->GetNext( nSectId) ;
}
// elimino eventuali sottosquadra
ICURVEPOVECTOR vpNucCrvs ;
vpNucCrvs.reserve( vpSects.size()) ;
for ( const auto& pSect : vpSects) {
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( IsNull( pCrvCompo) ||
! pCrvCompo->AddCurve( *pSect) ||
! pCrvCompo->RemoveUndercutOnY( LIN_TOL_STD, ANG_TOL_STD_DEG))
return false ;
vpNucCrvs.emplace_back( Release( pCrvCompo)) ;
}
// 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()) ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
Point3d ptStart ;
if ( ! vpNucCrvs[i]->GetStartPoint( ptStart))
return false ;
vIAsc.emplace_back( i, ptStart.x) ;
}
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") ;
return false ;
}
b3Raw.ToLoc( frSec) ;
Point3d ptMin = b3Raw.GetMin(),
ptMax = b3Raw.GetMax() ;
double dMinY = 5. ;
double 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.) ;
PtrOwner<ICurveComposite> pCompoRegLimit( CreateCurveComposite()) ;
if ( IsNull( pCompoRegLimit))
return false ;
pCompoRegLimit->AddPoint( ptLineMinYStart) ;
pCompoRegLimit->AddLine( ptLineMinYStart - Y_AX * LINE_EXT) ;
pCompoRegLimit->AddLine( ptLineMinYEnd - Y_AX * LINE_EXT) ;
pCompoRegLimit->AddLine( ptLineMinYEnd) ;
pCompoRegLimit->Close() ;
PtrOwner<ISurfFlatRegion> pSfrLimit( CreateSurfFlatRegion()) ;
if ( IsNull( pSfrLimit) || ! pSfrLimit->AddExtLoop( ::Release( pCompoRegLimit)))
return false ;
// unisco le diverse curve (ora aperte) in un unico profilo
PtrOwner<ICurveComposite> pCurve( CreateCurveComposite()) ;
if ( IsNull( pCurve))
return false ;
bool bFirst = true ;
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
if ( ! bFirst) {
Point3d ptStart ;
if ( ! vpNucCrvs[vIAsc[i].first]->GetStartPoint( ptStart) ||
! pCurve->AddLine( ptStart))
return false ;
}
if ( ! pCurve->AddCurve( Release( vpNucCrvs[vIAsc[i].first])))
return false ;
bFirst = false ;
}
// elimino tutti i tratti all'inizio e alla fine della sezione con tangenza sotto i 60deg
double dAngDegSplit = 60. ;
double dAngUN = 0. ;
if ( GetValInNotes( m_Params.m_sUserNotes, UN_LIMIT_ANG, dAngUN))
dAngDegSplit = max( 15. - EPS_ANG_SMALL, dAngUN) ;
if ( ! TrimVerticalSectionBounds( pCurve, dAngDegSplit))
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()) ;
// la curva ricavata deve essere sufficientemente distante dal fondo del grezzo
CRVCVECTOR ccClass ;
if ( ! pSfrLimit->GetCurveClassification( *pOvrCrv, EPS_SMALL, ccClass))
return false ;
ICURVEPOVECTOR vpCrvOut ; vpCrvOut.reserve( ccClass.size()) ;
for ( int i = 0 ; i < ssize( ccClass) ; ++ i) {
if ( ccClass[i].nClass != CRVC_IN)
vpCrvOut.emplace_back( pOvrCrv->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE)) ;
}
erase_if( vpCrvOut, []( const ICurve* pCrv) { return ( pCrv == nullptr || ! pCrv->IsValid()) ; }) ;
if ( vpCrvOut.empty())
return false ;
pCurve->Clear() ;
bFirst = true ;
for ( int i = 0 ; i < ssize( vpCrvOut) ; ++ i) {
if ( ! bFirst) {
Point3d ptStart ;
if ( ! vpCrvOut[i]->GetStartPoint( ptStart) || ! pCurve->AddLine( ptStart))
return false ;
}
if ( ! pCurve->AddCurve( Release( vpCrvOut[i])))
return false ;
bFirst = false ;
}
// eseguo trim (se richiesto)
if ( IsNull( pCurve) || ! TrimSection( pCurve))
return false ;
pSect = Release( pCurve) ;
return true ;
}
//----------------------------------------------------------------------------
bool
SawFinishing::CalculateSection( int nSectGrpId, ICurve*& pSect) const
{
// recupero le sezioni
ICURVEPVECTOR vpSects ;
@@ -1845,7 +2363,7 @@ SawFinishing::CalculateSection( int nSectGrpId, ICurve*& pSect)
//----------------------------------------------------------------------------
bool
SawFinishing::TrimSection( ICurve* pCrv)
SawFinishing::TrimSection( ICurve* pCrv) const
{
// se parametri di accorciamento iniziale e finale sono nulli, non faccio alcunché
if ( m_Params.m_dStartAddLen > - EPS_SMALL && m_Params.m_dEndAddLen > -EPS_SMALL)
@@ -2004,9 +2522,9 @@ SawFinishing::CalculateSectElevation( const Polygon3d& pgFacet, double& dElev) c
// calcolo l'elevazione iniziale
double dCurrElev = 0. ;
if ( ! PolygonElevationInClosedSurfTm( pgFacetL, *pStm, true, dCurrElev))
return false ;
return false ;
if ( dCurrElev > EPS_SMALL)
vRawElev.emplace_back( nStmId, dCurrElev) ;
vRawElev.emplace_back( nStmId, dCurrElev) ;
}
}
// passo al grezzo successivo
@@ -2038,9 +2556,9 @@ SawFinishing::CalculateSectElevation( const Polygon3d& pgFacet, double& dElev) c
}
b3Tool.Expand( MAX_DIST_RAW) ;
// verifico la reale interferenza dell'utensile con i diversi grezzi
for ( int i = 0 ; i < int( vRawElev.size()) ; ++ i) {
for ( int i = 0 ; i < ssize( vRawElev) ; ++ i) {
// box del grezzo
BBox3d b3Raw ;
BBox3d b3Raw ;
m_pGeomDB->GetGlobalBBox( vRawElev[i].first, b3Raw) ;
// confronto con il box dell'utensile nella posizione precedente
BBox3d b3CurrTool = b3Tool ;
@@ -2085,6 +2603,7 @@ SawFinishing::CalculateGuideLine( int nGuideId, const ICurve* pSect, Point3d& pt
nSectId = m_pGeomDB->GetNext( nSectId) ;
}
// per ogni sezione calcolo eventuale elevazione
double dMaxStartElev = 0., dMaxEndElev = 0. ;
for ( const ICurve* pCrvSect : vpSects) {
// applico offset radiale
OffsetCurve OffsCrv ;
@@ -2103,22 +2622,26 @@ SawFinishing::CalculateGuideLine( int nGuideId, const ICurve* pSect, Point3d& pt
if ( ! pgFacet.FromPolyLine( PL))
return false ;
// calcolo l'estensione della guida fino alla proiezione in eccesso del grezzo
double dSectStartElev = 0. ;
if ( ! CalculateSectElevation( pgFacet, dSectStartElev))
double dCurrStartElev = 0. ;
if ( ! CalculateSectElevation( pgFacet, dCurrStartElev))
return false ;
if ( dCurrStartElev > dMaxStartElev)
dMaxStartElev = dCurrStartElev ;
// calcolo l'estensione della guida fino alla proiezione in eccesso del grezzo
pgFacet.Translate( ptGdEnd - ptGdStart) ;
pgFacet.Invert() ;
double dSectEndElev = 0. ;
if ( ! CalculateSectElevation( pgFacet, dSectEndElev))
double dCurrEndElev = 0. ;
if ( ! CalculateSectElevation( pgFacet, dCurrEndElev))
return false ;
// estendo la guida delle quantità calcolate
if ( dSectStartElev > EPS_SMALL)
ptGdStart -= ( vtGdDir * dSectStartElev) ;
if ( dSectEndElev > EPS_SMALL)
ptGdEnd += ( vtGdDir * dSectEndElev) ;
if ( dCurrEndElev > dMaxEndElev)
dMaxEndElev = dCurrEndElev ;
}
}
// estendo la guida nel punto trovato
if ( dMaxEndElev > EPS_SMALL)
ptGdEnd += ( vtGdDir * dMaxEndElev) ;
if ( dMaxStartElev > EPS_SMALL)
ptGdStart -= ( vtGdDir * dMaxStartElev) ;
}
return true ;
@@ -3147,8 +3670,7 @@ SawFinishing::AddRetract( const Point3d& ptP, const Vector3d& vtCorr,
//----------------------------------------------------------------------------
bool
SawFinishing::CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide,
Vector3d& vtTool, Vector3d& vtCorr)
SawFinishing::CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide, Vector3d& vtTool, Vector3d& vtCorr) const
{
// Versore fresa : annullo la componente in Z e normalizzo
vtTool = vtTang ;
+7 -4
View File
@@ -85,9 +85,13 @@ class SawFinishing : public Machining
bool CalculateStraightAcrossToolPath( int nAuxId, int nClId) ;
bool CalculateCurvedAlongToolPath( int nAuxId, int nClId) ;
bool CalculateCurvedAcrossToolPath( int nAuxId, int nClId) ;
bool CalculateSection( int nSectGrpId, ICurve*& pSect) ;
bool TrimSection( ICurve* pCrv) ;
bool CalculateStraightSectionToolPath( int nAuxId, int nClId) ;
bool TrimVerticalSectionBounds( ICurveComposite* pSect, double dAngDeg) const ;
bool CalculateOffsetSection( int nSectGrpId, const Frame3d& frSec, ICurve*& pSect) const ;
bool CalculateSection( int nSectGrpId, ICurve*& pSect) const ;
bool TrimSection( ICurve* pCrv) 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 CalculateSectElevation( const Polygon3d& pgFacet, double& dElev) const ;
bool CalculateGuideLine( int nGuideId, const ICurve* pSect, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir,
int nSectGrpId, bool bExtendToRawBox) const ;
@@ -120,8 +124,7 @@ class SawFinishing : public Machining
bool AddCornerApproach( const Point3d& ptP, const Vector3d& vtCorr, const Vector3d& vtPrev,
double dSafeZ, double dElev, double dAppr) ;
bool AddRetract( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) ;
bool CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide,
Vector3d& vtTool, Vector3d& vtCorr) ;
bool CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide, Vector3d& vtTool, Vector3d& vtCorr) const ;
bool GetHeightOnSection( const ICurve* pSect, double dX, double dYmin, double dYmax, double& dY) ;
private :