EgtMachKernel :
- in SawFinishing aggiunto sottotipo "Section" - in SawFinishing correzioni varie.
This commit is contained in:
@@ -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
@@ -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
@@ -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 :
|
||||
|
||||
Reference in New Issue
Block a user