EgtMachKernel :
- in SawFinishing aggiunto sottotipo "Along5A" - in SawFinishing correzioni varie.
This commit is contained in:
+2
-2
@@ -2525,8 +2525,8 @@ Operation::VerifyMcentLineMidPoint( const Point3d& ptPrec, const Vector3d& vtDir
|
||||
bAxError = false ;
|
||||
Machine* pMachine = m_pMchMgr->GetCurrMachine() ;
|
||||
|
||||
// se disposizione non vanno fatti controlli
|
||||
if ( GetType() == OPER_DISP)
|
||||
// se disposizione o finitura di cornici con lama non vanno fatti controlli
|
||||
if ( GetType() == OPER_DISP || GetType() == OPER_SAWFINISHING)
|
||||
return true ;
|
||||
|
||||
// se superato il limite di ricursioni, non devo fare alcunché
|
||||
|
||||
+659
-28
@@ -24,6 +24,7 @@
|
||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveArc.h"
|
||||
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EGkCurveAux.h"
|
||||
#include "/EgtDev/Include/EGkSurfLocal.h"
|
||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||
@@ -59,6 +60,8 @@ using namespace std ;
|
||||
// 2715 = "Error in SawFinishing : post apply not calculable"
|
||||
// 2716 = "Error in SawFinishing : special apply not calculable"
|
||||
// 2717 = "Error in SawFinishing : CalculateSectionToolPath failed"
|
||||
// 2718 = "Error in SawFinishing : CalculateStraightAlong5AToolPath failed"
|
||||
// 2719 = "Error in SawFinishing : Splitting Section failed"
|
||||
// 2751 = "Warning in SawFinishing : Skipped entity (xx)"
|
||||
// 2752 = "Warning in SawFinishing : No machinable path"
|
||||
// 2753 = "Warning in SawFinishing : Tool name changed (xx)"
|
||||
@@ -565,35 +568,45 @@ SawFinishing::Apply( bool bRecalc, bool bPostApply)
|
||||
if ( m_Params.m_nSubType == SAWFIN_SUB_ALONG) {
|
||||
if ( m_bStraight) {
|
||||
if ( ! CalculateStraightAlongToolPath( nAuxId, nClId)) {
|
||||
m_pMchMgr->SetLastError( 2709, "Error in SawFinishing : CalculateAlongToolPath failed") ;
|
||||
return false ;
|
||||
m_pMchMgr->SetLastError( 2709, "Error in SawFinishing : CalculateAlongToolPath failed") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( ! CalculateCurvedAlongToolPath( nAuxId, nClId)) {
|
||||
m_pMchMgr->SetLastError( 2709, "Error in SawFinishing : CalculateAlongToolPath failed") ;
|
||||
return false ;
|
||||
m_pMchMgr->SetLastError( 2709, "Error in SawFinishing : CalculateAlongToolPath failed") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( m_Params.m_nSubType == SAWFIN_SUB_ACROSS) {
|
||||
if ( m_bStraight) {
|
||||
if ( ! CalculateStraightAcrossToolPath( nAuxId, nClId)) {
|
||||
m_pMchMgr->SetLastError( 2710, "Error in SawFinishing : CalculateAcrossToolPath failed") ;
|
||||
m_pMchMgr->SetLastError( 2710, "Error in SawFinishing : CalculateAcrossToolPath failed") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( ! CalculateCurvedAcrossToolPath( nAuxId, nClId)) {
|
||||
m_pMchMgr->SetLastError( 2710, "Error in SawFinishing : CalculateAcrossToolPath failed") ;
|
||||
m_pMchMgr->SetLastError( 2710, "Error in SawFinishing : CalculateAcrossToolPath failed") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( m_Params.m_nSubType == SAWFIN_SUB_SECTION) {
|
||||
if ( ! CalculateStraightSectionToolPath( nAuxId, nClId)) {
|
||||
m_pMchMgr->SetLastError( 2717, "Error in SawFinishing : CalculateSectionToolPath failed") ;
|
||||
return false ;
|
||||
if ( m_bStraight) {
|
||||
if ( ! CalculateStraightSectionToolPath( nAuxId, nClId)) {
|
||||
m_pMchMgr->SetLastError( 2717, "Error in SawFinishing : CalculateSectionToolPath failed") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( m_Params.m_nSubType == SAWFIN_SUB_ALONG_5A) {
|
||||
if ( m_bStraight) {
|
||||
if ( ! CalculateStraightAlong5AToolPath( nAuxId, nClId)) {
|
||||
m_pMchMgr->SetLastError( 2718, "Error in SawFinishing : CalculateStraightAlong5AToolPath failed") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,7 +1113,7 @@ SawFinishing::CalculateStraightAlongToolPath( int nAuxId, int nClId)
|
||||
Point3d ptGdStart, ptGdEnd ;
|
||||
Vector3d vtGdDir ;
|
||||
int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ;
|
||||
if ( ! CalculateGuideLine( nGuideId, pSect, ptGdStart, ptGdEnd, vtGdDir, nSectGrpId, false))
|
||||
if ( ! CalculateGuideLine( nGuideId, ptGdStart, ptGdEnd, vtGdDir, nSectGrpId, false))
|
||||
return false ;
|
||||
if ( m_Params.m_bInvert) {
|
||||
swap( ptGdStart, ptGdEnd) ;
|
||||
@@ -1295,7 +1308,7 @@ SawFinishing::CalculateStraightAcrossToolPath( int nAuxId, int nClId)
|
||||
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))
|
||||
if ( ! CalculateGuideLine( nGuideId, ptGdStart, ptGdEnd, vtGdDir, nSectGrpId, bExtend))
|
||||
return false ;
|
||||
Vector3d vtDeltaSect = vtGdDir * ( vtGdDir * ( ptGdStart - frSect.Orig())) ;
|
||||
if ( m_Params.m_bInvert) {
|
||||
@@ -1811,7 +1824,7 @@ SawFinishing::CalculateStraightSectionToolPath( int nAuxId, int nClId)
|
||||
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))
|
||||
if ( ! CalculateGuideLine( nGuideId, ptGdStart, ptGdEnd, vtGdDir, nSectGrpId, bExtend))
|
||||
return false ;
|
||||
if ( m_Params.m_bInvert) {
|
||||
swap( ptGdStart, ptGdEnd) ;
|
||||
@@ -1964,6 +1977,117 @@ SawFinishing::CalculateStraightSectionToolPath( int nAuxId, int nClId)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::CalculateStraightAlong5AToolPath( int nAuxId, int nClId)
|
||||
{
|
||||
// Recupero ed elaboro le sezioni per portarle ad essere la curva del centro in basso della lama
|
||||
int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ;
|
||||
SECTIONVECTOR vSections ;
|
||||
if ( ! Split5ASection( nSectGrpId, vSections)) {
|
||||
m_pMchMgr->SetLastError( 2719, "Error in SawFinishing : Splitting Section failed") ;
|
||||
return false ;
|
||||
}
|
||||
// recupero il riferimento globale delle sezioni
|
||||
Frame3d frSect ;
|
||||
m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ;
|
||||
// recupero il box globale delle sezioni
|
||||
BBox3d b3Sect ;
|
||||
m_pGeomDB->GetGlobalBBox( nSectGrpId, b3Sect) ;
|
||||
|
||||
// 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 ;
|
||||
}
|
||||
// se link di tipo Standard, questa viene convertita in Center, per la lavorazione corrente si effettuano le rotazioni della lama
|
||||
// sempre al di fuori del grezzo
|
||||
if ( m_Params.m_nLeadLinkType == SAWFIN_LL_STD) {
|
||||
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, ptGdStart, ptGdEnd, vtGdDir, nSectGrpId, false))
|
||||
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) ;
|
||||
|
||||
// Imposto dati comuni
|
||||
SetPathId( nPxId) ;
|
||||
|
||||
// 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) ;
|
||||
}
|
||||
|
||||
// elaboro le Section/SubSections
|
||||
if ( ! CalcAlong5ACuts( vSections, frSect, bExtend, ptGdStart, ptGdEnd, vtGdDir, dDepth, b3Raw, pStmRaw))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::ExtendPathToRaw( PolyLine& PL, const ISurfTriMesh* pStmRaw, double dExtraOut) const
|
||||
@@ -2312,21 +2436,20 @@ SawFinishing::CalculateSection( int nSectGrpId, ICurve*& pSect) const
|
||||
typedef vector<INDASC> INDASCVECTOR ; // vettore di coppie indice, ascissa
|
||||
INDASCVECTOR vIAsc ;
|
||||
vIAsc.reserve( vpNucCrvs.size()) ;
|
||||
for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) {
|
||||
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 ; }) ;
|
||||
sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) { return a.second > b.second ; }) ;
|
||||
|
||||
// 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 < int( vpNucCrvs.size()) ; ++ i) {
|
||||
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
|
||||
if ( ! bFirst) {
|
||||
Point3d ptStart ;
|
||||
if ( ! vpNucCrvs[vIAsc[i].first]->GetStartPoint( ptStart) ||
|
||||
@@ -2340,20 +2463,23 @@ SawFinishing::CalculateSection( int nSectGrpId, ICurve*& pSect) const
|
||||
|
||||
// offset radiale delle sezioni per il sovramateriale
|
||||
double dOffsR = GetOffsR() ;
|
||||
PtrOwner<ICurve> pOvrCrv ;
|
||||
OffsetCurve OffsCrv ;
|
||||
OffsCrv.Make( pCurve, dOffsR, ICurve::OFF_FILLET) ;
|
||||
pOvrCrv.Set( OffsCrv.GetLongerCurve()) ;
|
||||
PtrOwner<ICurve> pOvrCrv( OffsCrv.GetLongerCurve()) ;
|
||||
if ( IsNull( pOvrCrv) || ! pOvrCrv->IsValid())
|
||||
return false ;
|
||||
|
||||
// ricavo dalla sezione la curva per centro in basso della lama
|
||||
double dOffsX = 0.5 * m_TParams.m_dThick ;
|
||||
PtrOwner<ICurve> pCrv ;
|
||||
OffsetCurveOnX OffsCrvX ;
|
||||
OffsCrvX.Make( pOvrCrv, dOffsX) ;
|
||||
pCrv.Set( OffsCrvX.GetLongerCurve()) ;
|
||||
if ( ! OffsCrvX.Make( pOvrCrv, dOffsX))
|
||||
return false ;
|
||||
PtrOwner<ICurve> pCrv( OffsCrvX.GetLongerCurve()) ;
|
||||
if ( IsNull( pCrv) || ! pCrv->IsValid())
|
||||
return false ;
|
||||
|
||||
// eseguo trim (se richiesto)
|
||||
if ( IsNull( pCrv) || ! TrimSection( pCrv))
|
||||
if ( ! TrimSection( pCrv))
|
||||
return false ;
|
||||
|
||||
pSect = Release( pCrv) ;
|
||||
@@ -2366,7 +2492,7 @@ bool
|
||||
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)
|
||||
if ( m_Params.m_dStartAddLen > -EPS_SMALL && m_Params.m_dEndAddLen > -EPS_SMALL)
|
||||
return true ;
|
||||
|
||||
// box della sezione in locale
|
||||
@@ -2379,13 +2505,13 @@ SawFinishing::TrimSection( ICurve* pCrv) const
|
||||
ptMin.x -= m_Params.m_dStartAddLen ;
|
||||
ptMax.x += m_Params.m_dEndAddLen ;
|
||||
double dDimX = ptMax.x - ptMin.x ;
|
||||
double dDimY = ptMax.y - ptMin.y + 100 * EPS_SMALL ;
|
||||
double dDimY = ptMax.y - ptMin.y + 100. * EPS_SMALL ;
|
||||
|
||||
// regione del box nel piano XY
|
||||
PtrOwner<ISurfFlatRegion> pSfr( GetSurfFlatRegionRectangle( dDimX, dDimY)) ;
|
||||
if ( IsNull( pSfr))
|
||||
return false ;
|
||||
pSfr->Translate( Vector3d( ptMin.x, ptMin.y - 50 * EPS_SMALL, ptMin.z)) ;
|
||||
pSfr->Translate( Vector3d( ptMin.x, ptMin.y - 50. * EPS_SMALL, ptMin.z)) ;
|
||||
|
||||
// calcolo la classificazione della curva rispetto alla regione
|
||||
CRVCVECTOR ccClass ;
|
||||
@@ -2394,7 +2520,7 @@ SawFinishing::TrimSection( ICurve* pCrv) const
|
||||
|
||||
// determino l'intervallo di curva da conservare
|
||||
Intervals inOk ;
|
||||
for ( auto& ccOne : ccClass) {
|
||||
for ( const CrvClass& ccOne : ccClass) {
|
||||
if ( ccOne.nClass == CRVC_IN || ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M)
|
||||
inOk.Add( ccOne.dParS, ccOne.dParE) ;
|
||||
}
|
||||
@@ -2406,6 +2532,289 @@ SawFinishing::TrimSection( ICurve* pCrv) const
|
||||
return ( pCrv->TrimEndAtParam( dUmax) && pCrv->TrimStartAtParam( dUmin)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::Split5ASection( int nSectGrpId, SECTIONVECTOR& vSections) const
|
||||
{
|
||||
vSections.clear() ;
|
||||
|
||||
// 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
|
||||
ICRVCOMPOPOVECTOR 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)) ;
|
||||
}
|
||||
|
||||
// per ogni sezione vengono rimossi i tratti verticali
|
||||
ICRVCOMPOPOVECTOR vSimpleSections ;
|
||||
for ( int i = 0 ; i < ssize( vpNucCrvs) ; ++ i) {
|
||||
// se tratto non valido, non lo considero
|
||||
if ( IsNull( vpNucCrvs[i]) || ! vpNucCrvs[i]->IsValid())
|
||||
return false ;
|
||||
|
||||
// oriento la curva corrente per X decrescenti
|
||||
Point3d ptStart ; vpNucCrvs[i]->GetStartPoint( ptStart) ;
|
||||
Point3d ptEnd ; vpNucCrvs[i]->GetEndPoint( ptEnd) ;
|
||||
if ( ptEnd.x > ptStart.x)
|
||||
vpNucCrvs[i]->Invert() ;
|
||||
|
||||
// approssimo per la presenza di archi e classifico i tratti
|
||||
PolyLine PL ;
|
||||
vpNucCrvs[i]->ApproxWithLines( LIN_TOL_MID, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ;
|
||||
vpNucCrvs[i]->Clear() ;
|
||||
vpNucCrvs[i]->FromPolyLine( PL) ;
|
||||
INTVECTOR vnClass ;
|
||||
if ( ! ClassifySection( vpNucCrvs[i], vnClass))
|
||||
return false ;
|
||||
|
||||
// vettore delle parti di sezione validi senza tratti verticiali (e sottosquadra)
|
||||
ICRVCOMPOPOVECTOR vpNucCrvsNoVert ; vpNucCrvsNoVert.reserve( vnClass.size()) ;
|
||||
PtrOwner<ICurveComposite> pCompoTmp( nullptr) ;
|
||||
for ( int j = 0 ; j < ssize( vnClass) ; ++ j) {
|
||||
if ( vnClass[j] == CCL_VERT) {
|
||||
if ( ! IsNull( pCompoTmp) && pCompoTmp->IsValid())
|
||||
vpNucCrvsNoVert.emplace_back( ::Release( pCompoTmp)) ;
|
||||
}
|
||||
else {
|
||||
if ( IsNull( pCompoTmp))
|
||||
pCompoTmp.Set( CreateCurveComposite()) ;
|
||||
const ICurve* pCrv = vpNucCrvs[i]->GetCurve( j) ;
|
||||
if ( pCrv == nullptr || ! pCrv->IsValid())
|
||||
return false ;
|
||||
pCompoTmp->AddCurve( pCrv->Clone()) ;
|
||||
}
|
||||
}
|
||||
erase_if( vpNucCrvsNoVert, []( const PtrOwner<ICurveComposite>& pCompo) { return ( pCompo == nullptr || ! pCompo->IsValid()) ; }) ;
|
||||
for ( int j = 0 ; j < ssize( vpNucCrvsNoVert) ; ++ j) {
|
||||
if ( ! vSimpleSections.emplace_back( ::Release( vpNucCrvsNoVert[j])))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// dalle sezioni semplici recuperate eseguo l'Offset Radiale complessivo ( evito così interferenze con sezioni differenti)
|
||||
ICURVEPVECTOR vMySimpleSections ; vMySimpleSections.resize( vSimpleSections.size()) ;
|
||||
for ( int i = 0 ; i < ssize( vSimpleSections) ; ++ i)
|
||||
vMySimpleSections[i] = vSimpleSections[i] ;
|
||||
ICURVEPOVECTOR vMySections ;
|
||||
if ( ! CalcOffsetCurves( vMySimpleSections, vMySections, GetOffsR()))
|
||||
return false ;
|
||||
for ( int i = 0 ; i < ssize( vMySections) ; ++ i) {
|
||||
if ( vMySections[i] != nullptr && vMySections[i]->IsValid()) {
|
||||
vSections.resize( vSections.size() + 1) ;
|
||||
if ( ! vSections.back().pSection.Set( CreateCurveComposite()) || ! vSections.back().pSection->AddCurve( vMySections[i]->Clone()))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
erase_if( vSections, []( const SectionInfo& SectionInfo) {
|
||||
return ( SectionInfo.pSection == nullptr || ! SectionInfo.pSection->IsValid()) ;
|
||||
}) ;
|
||||
|
||||
// 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( vSections.size()) ;
|
||||
for ( int i = 0 ; i < ssize( vSections) ; ++ i) {
|
||||
Point3d ptStart ;
|
||||
if ( ! vSections[i].pSection->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 ; }) ;
|
||||
for ( int nNewPos = 0 ; nNewPos < ssize( vIAsc) ; ++ nNewPos) {
|
||||
int nOldPos = vIAsc[nNewPos].first ;
|
||||
if ( nOldPos == nNewPos)
|
||||
continue ;
|
||||
swap( vSections[nNewPos], vSections[nOldPos]) ;
|
||||
swap( vIAsc[nNewPos].first, vIAsc[nOldPos].first) ;
|
||||
}
|
||||
|
||||
// !<-- NB:
|
||||
// - Una Section semplice non presente tratti verticali e non presenta tratti in sottosquadra
|
||||
// - Una Section semplice è orientata per X decrescente
|
||||
// - Le sue SubSections sono anch'esse orientate per X decrescente
|
||||
|
||||
// recupero angolo di Split iniziale e finale per i tratti
|
||||
double dAngDegSplit = 60. ;
|
||||
double dAngUN = 0. ;
|
||||
if ( GetValInNotes( m_Params.m_sUserNotes, UN_LIMIT_ANG, dAngUN))
|
||||
dAngDegSplit = max( 15. - EPS_ANG_SMALL, dAngUN) ;
|
||||
|
||||
// ---------------------------- funzioni ausiliarie semplici -------------------------------------
|
||||
auto AddSubSection = [&]( SUBSECTIONVECTOR& vSubSections, PtrOwner<ICurveComposite>& pCompo, int nHeadSide) {
|
||||
if ( IsNull( pCompo) || ! pCompo->IsValid())
|
||||
return false ;
|
||||
vSubSections.resize( vSubSections.size() + 1) ;
|
||||
vSubSections.back().pSubSection.Set( ::Release( pCompo)) ;
|
||||
vSubSections.back().nHeadSide = nHeadSide ;
|
||||
return true ;
|
||||
} ;
|
||||
auto GetHeadSide = [&]( int nClass) {
|
||||
if ( nClass == CCL_FALL)
|
||||
return int( SAWFIN_HS_RIGHT) ;
|
||||
else if ( nClass == CCL_RISE)
|
||||
return int( SAWFIN_HS_LEFT) ;
|
||||
else
|
||||
return m_Params.m_nHeadSide ;
|
||||
} ;
|
||||
|
||||
// per ogni sezione semplice
|
||||
for ( int i = 0 ; i < ssize( vSections) ; ++ i) {
|
||||
|
||||
// riferimenti
|
||||
SectionInfo& CurrSection = vSections[i] ;
|
||||
SUBSECTIONVECTOR& vCurrSubSections = CurrSection.vSubSections ;
|
||||
|
||||
// elimino tutti i tratti all'inizio e alla fine della sezione con tangenza sotto i 60deg
|
||||
if ( ! TrimVerticalSectionBounds( CurrSection.pSection, dAngDegSplit))
|
||||
return false ;
|
||||
// eseguo trim della parte iniziale e finale (se richiesto)
|
||||
if ( ! TrimSection( CurrSection.pSection))
|
||||
return false ;
|
||||
// Classifico i tratti a seconda della pendenza (salita, discesa, verticale, orizzontale)
|
||||
INTVECTOR vnClass ;
|
||||
if ( ! ClassifySection( CurrSection.pSection, vnClass))
|
||||
return false ;
|
||||
|
||||
// se una sola classificazione presente
|
||||
if ( ssize( vnClass) == 1) {
|
||||
PtrOwner<ICurveComposite> pSubSection( CloneCurveComposite( CurrSection.pSection)) ;
|
||||
return AddSubSection( vCurrSubSections, pSubSection, vnClass[0]) ;
|
||||
}
|
||||
|
||||
// scrorro i tratti correnti
|
||||
bool bCanSwapHead = true ;
|
||||
for ( int i = 1 ; i < ssize( vnClass) ; ++ i) {
|
||||
if ( i == 1) {
|
||||
// inserisco il primo elemento
|
||||
PtrOwner<ICurveComposite> pCompoSubSect( ConvertCurveToComposite( CurrSection.pSection->CopyParamRange( double( i - 1), double( i)))) ;
|
||||
if ( ! AddSubSection( vCurrSubSections, pCompoSubSect, GetHeadSide( vnClass[0])))
|
||||
return false ;
|
||||
}
|
||||
// classificazione corrente
|
||||
const int& nCurrClass = vnClass[i] ;
|
||||
// classificazione precedente
|
||||
const int& nPrevClass = vnClass[i - 1] ;
|
||||
// parametri per copia sotto-tratto corrente
|
||||
double dUS = double( i) ;
|
||||
double dUE = double( i + 1) ;
|
||||
PtrOwner<ICurveComposite> pCompoSub( ConvertCurveToComposite( CurrSection.pSection->CopyParamRange( dUS, dUE))) ;
|
||||
if ( IsNull( pCompoSub) || ! pCompoSub->IsValid())
|
||||
return false ;
|
||||
switch ( nCurrClass) {
|
||||
// --- classificazione corrente Flat o Small
|
||||
case CCL_FLAT :
|
||||
case CCL_SMALL :
|
||||
{
|
||||
// a prescindere dai valori precedenti si aggiunge semplicemente il tratto di sezione
|
||||
if ( ! vCurrSubSections.back().pSubSection->AddCurve( ::Release( pCompoSub)))
|
||||
return false ;
|
||||
bCanSwapHead = ( bCanSwapHead && ( nPrevClass != CCL_RISE && nPrevClass != CCL_FALL)) ;
|
||||
break ;
|
||||
}
|
||||
// --- classificazione corrente Fall (la testa deve essere a destra)
|
||||
case CCL_FALL : {
|
||||
// se la precedente è flat, veticale o small
|
||||
if ( nPrevClass == CCL_FLAT || nPrevClass == CCL_SMALL) {
|
||||
if ( vCurrSubSections.back().nHeadSide == SAWFIN_HS_RIGHT) {
|
||||
// allungo il percorso precedente
|
||||
if ( ! vCurrSubSections.back().pSubSection->AddCurve( ::Release( pCompoSub)))
|
||||
return false ;
|
||||
// non posso swappare la testa
|
||||
bCanSwapHead = false ;
|
||||
}
|
||||
else if ( bCanSwapHead) {
|
||||
// inverto la testa del percorso precedente e mi collego
|
||||
vCurrSubSections.back().nHeadSide = SAWFIN_HS_RIGHT ;
|
||||
if ( ! vCurrSubSections.back().pSubSection->AddCurve( ::Release( pCompoSub)))
|
||||
return false ;
|
||||
bCanSwapHead = false ;
|
||||
}
|
||||
else {
|
||||
// nuovo percorso
|
||||
PtrOwner<ICurveComposite> pCompoSubSect( ::Release( pCompoSub)) ;
|
||||
if ( ! AddSubSection( vCurrSubSections, pCompoSubSect, SAWFIN_HS_RIGHT))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se la precedente è fall
|
||||
else if ( nPrevClass == CCL_FALL) {
|
||||
// allungo il percorso precedente
|
||||
if ( ! vCurrSubSections.back().pSubSection->AddCurve( ::Release( pCompoSub)))
|
||||
return false ;
|
||||
}
|
||||
// se la precedente è Rise
|
||||
else if ( nPrevClass == CCL_RISE) {
|
||||
// definisco un nuovo percorso
|
||||
PtrOwner<ICurveComposite> pCompoSubSect( ::Release( pCompoSub)) ;
|
||||
if ( ! AddSubSection( vCurrSubSections, pCompoSubSect, SAWFIN_HS_RIGHT))
|
||||
return false ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
// --- classificazione corrente Rise (la testa deve essere a sinistra)
|
||||
case CCL_RISE : {
|
||||
// se la precedente è flat, veticale o small
|
||||
if ( nPrevClass == CCL_FLAT || nPrevClass == CCL_SMALL) {
|
||||
if ( vCurrSubSections.back().nHeadSide == SAWFIN_HS_LEFT) {
|
||||
// allungo il percorso precedente
|
||||
if ( ! vCurrSubSections.back().pSubSection->AddCurve( ::Release( pCompoSub)))
|
||||
return false ;
|
||||
// non posso swappare la testa
|
||||
bCanSwapHead = false ;
|
||||
}
|
||||
else if ( bCanSwapHead) {
|
||||
// inverto la testa del percorso precedente e mi collego
|
||||
vCurrSubSections.back().nHeadSide = SAWFIN_HS_LEFT ;
|
||||
if ( ! vCurrSubSections.back().pSubSection->AddCurve( ::Release( pCompoSub)))
|
||||
return false ;
|
||||
bCanSwapHead = false ;
|
||||
}
|
||||
else {
|
||||
// nuovo percorso
|
||||
PtrOwner<ICurveComposite> pCompoSubSect( ::Release( pCompoSub)) ;
|
||||
if ( ! AddSubSection( vCurrSubSections, pCompoSubSect, SAWFIN_HS_LEFT))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se la precedente è fall
|
||||
else if ( nPrevClass == CCL_FALL) {
|
||||
// definisco un nuovo percorso
|
||||
PtrOwner<ICurveComposite> pCompoSubSect( ::Release( pCompoSub)) ;
|
||||
if ( ! AddSubSection( vCurrSubSections, pCompoSubSect, SAWFIN_HS_LEFT))
|
||||
return false ;
|
||||
}
|
||||
// se la precedente è Rise
|
||||
else if ( nPrevClass == CCL_RISE) {
|
||||
// allungo il percorso precedente
|
||||
if ( ! vCurrSubSections.back().pSubSection->AddCurve( ::Release( pCompoSub)))
|
||||
return false ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::AdaptGuideLineToRaw( Point3d& ptGdStart, Point3d& ptGdEnd, const Vector3d& vtGdDir, bool bExtend, const ISurfTriMesh* pStmRaw) const
|
||||
@@ -2573,7 +2982,7 @@ SawFinishing::CalculateSectElevation( const Polygon3d& pgFacet, double& dElev) c
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::CalculateGuideLine( int nGuideId, const ICurve* pSect, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir,
|
||||
SawFinishing::CalculateGuideLine( int nGuideId, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir,
|
||||
int nSectGrpId, bool bExtendToRawBox) const
|
||||
{
|
||||
// recupero la linea guida
|
||||
@@ -2649,7 +3058,7 @@ SawFinishing::CalculateGuideLine( int nGuideId, const ICurve* pSect, Point3d& pt
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::ClassifySection( ICurve* pCrv, INTVECTOR& vnClass)
|
||||
SawFinishing::ClassifySection( ICurve* pCrv, INTVECTOR& vnClass) const
|
||||
{
|
||||
const ICurveComposite* pCompo = GetCurveComposite( pCrv) ;
|
||||
if ( pCompo != nullptr) {
|
||||
@@ -2872,6 +3281,228 @@ SawFinishing::CalcAlongStdCuts( ICurve* pSect, double dUmin, double dUmax,
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::CalcCAvSect5Ax( const ICurveComposite* pSubSect, const SECTIONVECTOR& vSections, const Vector3d& vtTool, const Vector3d& vtCorr,
|
||||
const Point3d& ptP, double& dElev, bool& bOtherCollision) const
|
||||
{
|
||||
// verifico la validità della curva
|
||||
if ( pSubSect == nullptr || ! pSubSect->IsValid())
|
||||
return false ;
|
||||
bOtherCollision = false ;
|
||||
|
||||
// definisco il numero di punti di campionamento progressivi
|
||||
const int MAX_NUM = 3 ;
|
||||
const double LINE_LEN = 1e4 ;
|
||||
double dSqMaxElev = EPS_ZERO ;
|
||||
PtrOwner<ICurveLine> pLineInters( CreateCurveLine()) ;
|
||||
if ( IsNull( pLineInters) || ! pLineInters->Set( ptP, ptP + vtCorr * LINE_LEN))
|
||||
return false ;
|
||||
for ( int i = 0 ; i < MAX_NUM ; ++ i) {
|
||||
if ( i > 0)
|
||||
pLineInters->Translate( ( m_TParams.m_dThick) / ( MAX_NUM - 1) * vtTool) ;
|
||||
Point3d ptLineS ; pLineInters->GetStartPoint( ptLineS) ;
|
||||
IntersCurveCurve ICC( *pLineInters, *pSubSect) ;
|
||||
for ( int j = ICC.GetIntersCount() - 1 ; j >= 0 ; -- j) {
|
||||
IntCrvCrvInfo aInfo ;
|
||||
if ( ICC.GetIntCrvCrvInfo( j, aInfo))
|
||||
dSqMaxElev = max( dSqMaxElev, ( SqDist( ptLineS, ( aInfo.bOverlap ? aInfo.IciA[1].ptI : aInfo.IciA[0].ptI)))) ;
|
||||
}
|
||||
|
||||
// controllo se la linea ricavata interseca le sezioni presenti
|
||||
double dSafeShift = 1. + sqrt( dSqMaxElev) ;
|
||||
pLineInters->Translate( dSafeShift * vtCorr) ;
|
||||
for ( int j = 0 ; j < ssize( vSections) ; ++ j) {
|
||||
if ( vSections[j].pSection != nullptr && vSections[j].pSection->IsValid()) {
|
||||
IntersCurveCurve ICC( *pLineInters, *vSections[j].pSection) ;
|
||||
if ( ICC.GetIntersCount() > 0) {
|
||||
bOtherCollision = true ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
pLineInters->Translate( - dSafeShift * vtCorr) ; // ritorno in posizione originale
|
||||
}
|
||||
|
||||
dElev = sqrt( dSqMaxElev) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& frSect, bool bExtend,
|
||||
const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, double dDepth,
|
||||
const BBox3d& b3Raw, const ISurfTriMesh* pStmRaw)
|
||||
{
|
||||
// se non ho sezioni da lavorare, non faccio nulla
|
||||
if ( vSections.empty()) {
|
||||
m_pMchMgr->SetWarning( 2752, "Warning in SawFinishing : No machinable path") ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// determino angolo limite di inclinazione dell'utensile
|
||||
double dAngDegSplit = 60. ;
|
||||
double dAngUN = 0. ;
|
||||
if ( GetValInNotes( m_Params.m_sUserNotes, UN_LIMIT_ANG, dAngUN))
|
||||
dAngDegSplit = max( 15. - EPS_ANG_SMALL, dAngUN) ;
|
||||
double dCosToolLimit = cos( dAngDegSplit * DEGTORAD) ;
|
||||
|
||||
// determino quota Zmassima dal Box del grezzo in globale
|
||||
double dRawMaxZ = b3Raw.GetMax().z ;
|
||||
|
||||
// scorro le sezioni
|
||||
for ( int nSect = 0 ; nSect < ssize( vSections) ; ++ nSect) {
|
||||
|
||||
// recupero la sezione
|
||||
const SectionInfo& Section = vSections[nSect] ;
|
||||
if ( Section.pSection == nullptr || ! Section.pSection->IsValid())
|
||||
continue ;
|
||||
|
||||
// scorro le SubSection ottenute
|
||||
for ( int nSubSect = 0 ; nSubSect < ssize( Section.vSubSections) ; ++ nSubSect) {
|
||||
|
||||
// recupero la SubSection corrente, se non valida, passo alla successiva
|
||||
const SubSectionInfo& SubSection = Section.vSubSections[nSubSect] ;
|
||||
PtrOwner<ICurveComposite> pSubSect( CloneCurveComposite( SubSection.pSubSection)) ;
|
||||
if ( pSubSect == nullptr || ! pSubSect->IsValid())
|
||||
continue ;
|
||||
// essendo l'utensile inclinato e la testa con orientamento forzato è meglio estendere la sezione per evitare lavorazioni
|
||||
// a filo dei suoi bordi
|
||||
pSubSect->ExtendStartByLen( 50. * EPS_SMALL) ;
|
||||
pSubSect->ExtendEndByLen( 50. * EPS_SMALL) ;
|
||||
|
||||
// calcolo della lunghezza dello step e del numero di step complessivi
|
||||
double dStep = max( m_Params.m_dSideStep, 10. * EPS_SMALL) ;
|
||||
double dLen ;
|
||||
if ( ! pSubSect->GetLength( dLen))
|
||||
return false ;
|
||||
double dL = dLen ;
|
||||
if ( dL < 10. * EPS_SMALL)
|
||||
return true ;
|
||||
int nStep = static_cast<int>( ceil( dL / dStep)) ;
|
||||
dStep = dL / nStep ;
|
||||
nStep ++ ;
|
||||
|
||||
// Ciclo sulle passate
|
||||
double dLastElev ;
|
||||
Point3d ptStartPrev ;
|
||||
for ( int i = 0 ; i <= nStep ; ++ i) {
|
||||
// coordinate nel punto, del versore correzione e del versore utensile
|
||||
double dLcurr = i * dStep ;
|
||||
double dU ; pSubSect->GetParamAtLength( dLcurr, dU) ;
|
||||
Point3d ptP ;
|
||||
Vector3d vtTan, vtPerp ;
|
||||
if ( ! pSubSect->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP, &vtTan) || ! vtTan.Normalize())
|
||||
return false ;
|
||||
Vector3d vtCorr = GetToGlob( vtTan, frSect) ;
|
||||
vtCorr.Rotate( vtGdDir, m_Params.m_bInvert ? - ANG_RIGHT : ANG_RIGHT) ;
|
||||
Vector3d vtTool = GetToGlob( vtTan, frSect) ;
|
||||
// determino la posizione della testa
|
||||
if ( vtTool.z < - EPS_ZERO)
|
||||
vtTool.Invert() ; // NB. vtTool deve sempre avere la componente Z come positiva
|
||||
|
||||
// se lama più inclinata della soglia, passo allo step successivo
|
||||
if ( vtCorr * Z_AX < dCosToolLimit)
|
||||
continue ;
|
||||
|
||||
// verifico posizionando la lama nel punto corrente se devo sposarmi per evitare collisione con la sezione
|
||||
double dSectElev = 0. ;
|
||||
bool bOtherColl = false ;
|
||||
if ( ! CalcCAvSect5Ax( pSubSect, vSections, GetToLoc( vtTool, frSect), GetToLoc( vtCorr, frSect), ptP, dSectElev, bOtherColl)) {
|
||||
m_pMchMgr->SetLastError( 2708, "Error in SawFinishing : GetElevation") ;
|
||||
return false ;
|
||||
}
|
||||
// se collisione con altra sezione, passo allo step successivo ( non inserisco la passata corrente)
|
||||
if ( bOtherColl)
|
||||
continue ;
|
||||
|
||||
// definisco gli estremi del tratto rettilineo in globale
|
||||
Point3d ptPCAvSect = GetToGlob( ptP, frSect) + vtCorr * dSectElev ;
|
||||
Point3d ptStart = ptPCAvSect ;
|
||||
Point3d ptEnd = ptPCAvSect + vtGdDir * ( Dist( ptGdStart, ptGdEnd)) ;
|
||||
|
||||
// verifico eventuale estensione degli estremi sul grezzo
|
||||
if ( bExtend) {
|
||||
if ( ! AdaptGuideLineToRaw( ptStart, ptEnd, vtGdDir, bExtend, pStmRaw))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// determino l'elevazione del taglio (considerando l'elevazione verticiale)
|
||||
Vector3d vtThick = vtTool * m_TParams.m_dThick ;
|
||||
double dElev, dElev2 ;
|
||||
if ( ! GetElevation( m_nPhase, ptStart, ptEnd, Z_AX, dElev) ||
|
||||
! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, Z_AX, dElev2)) {
|
||||
m_pMchMgr->SetLastError( 2708, "Error in SawFinishing : GetElevation") ;
|
||||
return false ;
|
||||
}
|
||||
dElev = max( dElev, dElev2) ;
|
||||
if ( dElev < EPS_SMALL)
|
||||
dElev = max( max( dRawMaxZ - ptStart.z, dRawMaxZ - ptEnd.z), 0.) ;
|
||||
// la confronto con il massimo affondamento e con la massima lavorazione della lama. Se sotto alla massima Depth allora riporto
|
||||
// l'utensile in verticale e ricalcolo il punto più adatto in z per il tratto lineare
|
||||
double dMaxDepth = min( dDepth, m_TParams.m_dMaxMat) ;
|
||||
if ( dElev > dMaxDepth) {
|
||||
// modifica versore correzione e direzione utensile
|
||||
vtTool.z = 0. ;
|
||||
if ( ! vtTool.Normalize())
|
||||
return false ;
|
||||
vtCorr = Z_AX ;
|
||||
double dElevTmp = 0. ;
|
||||
if ( ! CalcCAvSect5Ax( pSubSect, vSections, GetToLoc( vtTool, frSect), GetToLoc( vtCorr, frSect), ptP, dElevTmp, bOtherColl)) {
|
||||
m_pMchMgr->SetLastError( 2708, "Error in SawFinishing : GetElevation") ;
|
||||
return false ;
|
||||
}
|
||||
if ( bOtherColl)
|
||||
continue ;
|
||||
ptPCAvSect = GetToGlob( ptP, frSect) + vtCorr * dElevTmp ;
|
||||
double dElev3 ;
|
||||
if ( ! GetElevation( m_nPhase, ptPCAvSect, vtTool, m_TParams.m_dDiam / 2., m_TParams.m_dLen, vtCorr, dElev3)) {
|
||||
m_pMchMgr->SetLastError( 2708, "Error in SawFinishing : GetElevation") ;
|
||||
return false ;
|
||||
}
|
||||
Point3d ptPTopRaw = ptPCAvSect + ( dElev3 - m_TParams.m_dDiam / 2.) * vtCorr ;
|
||||
ptStart.z = max( ptPTopRaw.z - dMaxDepth, ptPCAvSect.z) ;
|
||||
ptEnd.z = max( ptPTopRaw.z - dMaxDepth, ptPCAvSect.z) ;
|
||||
dElev = dMaxDepth ;
|
||||
}
|
||||
|
||||
// Imposto dati comune
|
||||
SetToolDir( vtTool) ;
|
||||
SetCorrAuxDir( vtCorr) ;
|
||||
// se diverso da precedente, eseguo il taglio
|
||||
bool bFirst = ( i == 0) ;
|
||||
dElev = dElev / max( EPS_SMALL, ( vtCorr * Z_AX)) ; // non serve fare il max, ma meglio prevenire...
|
||||
if ( bFirst || ! AreSamePointEpsilon( ptStart, ptStartPrev, 10. * EPS_SMALL)) {
|
||||
if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) {
|
||||
if ( ! CalcAlongOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bExtend, false))
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
if ( ! CalcAlongZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bExtend, false, bFirst))
|
||||
return false ;
|
||||
}
|
||||
// salvo dati correnti
|
||||
dLastElev = dElev ;
|
||||
ptStartPrev = ptStart ;
|
||||
}
|
||||
}
|
||||
// se ZigZag e non centrato aggiungo risalita
|
||||
if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG && m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) {
|
||||
// recupero distanza di sicurezza
|
||||
double dSafeZ = GetSafeZ() ;
|
||||
// lunghezza di approccio/retrazione
|
||||
double dAppr = m_Params.m_dStartPos ;
|
||||
// aggiungo retrazione
|
||||
Point3d ptNewEnd ;
|
||||
if ( ! GetCurrPos( ptNewEnd) || ! AddRetract( ptNewEnd, Z_AX, dSafeZ, dLastElev, dAppr))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SawFinishing::CalcAlongOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir,
|
||||
|
||||
+25
-2
@@ -25,6 +25,22 @@ class ICurveComposite ;
|
||||
class ISurfTriMesh ;
|
||||
class Polygon3d ;
|
||||
|
||||
// Definizione strutture per Section/SubSection ------------------------------
|
||||
struct SubSectionInfo {
|
||||
PtrOwner<ICurveComposite> pSubSection ;
|
||||
int nHeadSide ;
|
||||
SubSectionInfo()
|
||||
: pSubSection( nullptr), nHeadSide( -1) {} ;
|
||||
} ;
|
||||
typedef std::vector<SubSectionInfo> SUBSECTIONVECTOR ;
|
||||
struct SectionInfo {
|
||||
PtrOwner<ICurveComposite> pSection ;
|
||||
SUBSECTIONVECTOR vSubSections ;
|
||||
SectionInfo()
|
||||
: pSection( nullptr), vSubSections( SUBSECTIONVECTOR{}) {} ;
|
||||
} ;
|
||||
typedef std::vector<SectionInfo> SECTIONVECTOR ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class SawFinishing : public Machining
|
||||
{
|
||||
@@ -86,22 +102,29 @@ class SawFinishing : public Machining
|
||||
bool CalculateCurvedAlongToolPath( int nAuxId, int nClId) ;
|
||||
bool CalculateCurvedAcrossToolPath( int nAuxId, int nClId) ;
|
||||
bool CalculateStraightSectionToolPath( int nAuxId, int nClId) ;
|
||||
bool CalculateStraightAlong5AToolPath( 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 Split5ASection( int nSectGrpId, SECTIONVECTOR& vSubSections) 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,
|
||||
bool CalculateGuideLine( int nGuideId, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir,
|
||||
int nSectGrpId, bool bExtendToRawBox) const ;
|
||||
bool ClassifySection( ICurve* pCrv, INTVECTOR& vnClass) ;
|
||||
bool ClassifySection( ICurve* pCrv, INTVECTOR& vnClass) const ;
|
||||
bool CalcCAvSect5Ax( const ICurveComposite* pSubSect, const SECTIONVECTOR& vSections, const Vector3d& vtTool, const Vector3d& vtCorr, const Point3d& ptP,
|
||||
double& dElev, bool& bOtherCollision) const ;
|
||||
bool CalcAlongVerticalCuts( ICurve* pSect, int nUmin, int nUmax, const Frame3d& frSect, bool bExtend, const Point3d& ptGdStart,
|
||||
const Point3d& ptGdEnd, const Vector3d& vtGdDir, double dDepth, double dRaxMaxZ,
|
||||
const Vector3d& vtTool, const Vector3d& vtCorr, const ISurfTriMesh* pStmRaw) ;
|
||||
bool CalcAlongStdCuts( ICurve* pSect, double dUmin, double dUmax, bool bSkipMin, bool bSkipMax, bool bInvert, const Frame3d& frSect,
|
||||
bool bExtend, const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, double dDepth,
|
||||
double dRawMaxZ, const Vector3d& vtTool, const Vector3d& vtCorr, const ISurfTriMesh* pStmRaw) ;
|
||||
bool CalcAlong5ACuts( const SECTIONVECTOR& vSections, const Frame3d& frSect, bool bExtend,
|
||||
const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, double dDepth,
|
||||
const BBox3d& b3Raw, const ISurfTriMesh* pStmRaw) ;
|
||||
bool CalcAlongOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir,
|
||||
const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bExtend, bool bVert) ;
|
||||
bool CalcAlongZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir,
|
||||
|
||||
@@ -391,7 +391,8 @@ SawFinishingData::VerifyStepType( int nVal) const
|
||||
bool
|
||||
SawFinishingData::VerifySubType( int nVal) const
|
||||
{
|
||||
return ( nVal == SAWFIN_SUB_ALONG || nVal == SAWFIN_SUB_ACROSS) ;
|
||||
return ( nVal == SAWFIN_SUB_ALONG || nVal == SAWFIN_SUB_ACROSS || nVal == SAWFIN_SUB_SECTION ||
|
||||
nVal == SAWFIN_SUB_ALONG_5A) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user